Compare commits
948 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
9e1a3e336b
|
|||
|
e897cfbd14
|
|||
|
5a92edc6b0
|
|||
|
c32ed6ce28
|
|||
|
6631ba0641
|
|||
|
98320fe174
|
|||
|
b8105cf9cc
|
|||
|
d7a93916e3
|
|||
|
cec9dfc0e1
|
|||
|
893b3d9fff
|
|||
|
7de9d1a819
|
|||
|
8748a63532
|
|||
|
5eed025419
|
|||
|
f2e416b0f8
|
|||
|
1c7043fa3e
|
|||
|
2bd4c5b35e
|
|||
|
f4481a84f4
|
|||
|
4c740690e0
|
|||
|
128c79cdc4
|
|||
|
7082677b2f
|
|||
|
257d8bbade
|
|||
|
a6ca71b131
|
|||
|
8634716aa7
|
|||
|
8a12629740
|
|||
|
b07f2f7a59
|
|||
|
da90ef8e40
|
|||
|
197f684488
|
|||
|
e63838faeb
|
|||
|
89b37db48e
|
|||
|
68e7f44a76
|
|||
|
2490e2cc68
|
|||
|
b2f4c065ea
|
|||
|
20b40597fd
|
|||
|
7df78838aa
|
|||
|
b3bd9c6cf0
|
|||
|
dadff8329e
|
|||
|
c30b7db041
|
|||
|
6aa100f12c
|
|||
|
5d457f3d4b
|
|||
|
af0d34beb9
|
|||
|
d122917f83
|
|||
|
612501217c
|
|||
|
d86ab8f9c0
|
|||
|
5a33563722
|
|||
|
1c850b12ec
|
|||
|
140b4495df
|
|||
|
8b0b25ed0a
|
|||
|
eacdcfb980
|
|||
|
132e7aa937
|
|||
|
d9f3b69dde
|
|||
|
de753070a8
|
|||
|
c1c6e6a588
|
|||
|
291147503f
|
|||
|
dbf7dfab82
|
|||
|
b753464608
|
|||
|
544ef298aa
|
|||
|
065a2d182f
|
|||
|
f4470ccbe7
|
|||
|
71ad4869ce
|
|||
|
09dc6782c8
|
|||
|
0cebb2dc52
|
|||
|
0724ca8eb3
|
|||
|
53991e54e1
|
|||
|
df7ae1c6ea
|
|||
|
d1f5d9aa88
|
|||
|
a54d70bed4
|
|||
|
bcde5c628a
|
|||
|
f241eb0a18
|
|||
|
74c0c936f6
|
|||
|
79babc916a
|
|||
|
a08bf9f804
|
|||
|
966577cd58
|
|||
|
8f20c8f67c
|
|||
|
f6c04b2d00
|
|||
|
0474c76a3d
|
|||
|
7a29a072be
|
|||
|
24c2ecb8dd
|
|||
|
7a1cea63bf
|
|||
|
e600aebaae
|
|||
|
5e45ad3417
|
|||
|
79e971cb76
|
|||
|
edee581ecf
|
|||
|
f7e077a7c5
|
|||
|
6a9504fd5f
|
|||
|
6d256e6512
|
|||
|
cf383fa026
|
|||
|
c86536d660
|
|||
|
dba87d6213
|
|||
|
52f9d399ca
|
|||
|
7b7a962f19
|
|||
|
c37722c29a
|
|||
|
ca509d3a86
|
|||
|
bf79e46411
|
|||
|
08821eb440
|
|||
|
d7878b5564
|
|||
|
0b52ae80dd
|
|||
|
3e46d8b4b4
|
|||
|
1655ae3562
|
|||
|
dda325bbbf
|
|||
|
c326c2a095
|
|||
|
bf386e2286
|
|||
|
e822e13dc8
|
|||
|
cc2c008bfd
|
|||
|
b8a8013d4c
|
|||
|
12ed77aeb1
|
|||
|
7476048da6
|
|||
|
8a307790c0
|
|||
|
a49b10ed2d
|
|||
|
6a2da642b0
|
|||
|
b836c77950
|
|||
|
2aa4eee20d
|
|||
|
9ada82c4aa
|
|||
|
aa9b83f740
|
|||
|
4ddfd2cd3a
|
|||
|
d15f5e4fa4
|
|||
|
2e455f97ac
|
|||
|
f664cc1a53
|
|||
|
ae505f3201
|
|||
|
d5433cddf1
|
|||
|
52773a271c
|
|||
|
e9311989ab
|
|||
|
7b63c01033
|
|||
| 5972b2bb39 | |||
| f182978ea5 | |||
| ebb8132808 | |||
| 1bd1762258 | |||
| 00b0e251f4 | |||
| 14e32df8c9 | |||
| aa938f05ca | |||
| 4583ab28ed | |||
| 9c0cd6eb5e | |||
| 32c30cf536 | |||
| a8b7a9e122 | |||
| d07ff5b881 | |||
| 66fae598c2 | |||
| 589e889822 | |||
| 89249f1297 | |||
| 2bd56c87e4 | |||
| 204688464e | |||
| 1d0956abab | |||
| c2013ff47f | |||
| 624bf47c8d | |||
| cdd395efa5 | |||
| 47f6e2234c | |||
| 1648092cd5 | |||
| 99fbf6ca27 | |||
| f050fc2316 | |||
| 1015baf111 | |||
| 04f0a2f808 | |||
| 1da240afb9 | |||
| 77a00f5989 | |||
| f3d6494ae5 | |||
| 8edd0ef07a | |||
| 3855ea9fa7 | |||
| a81839fd9c | |||
| 03035f038f | |||
| baa870edbd | |||
| c8bc23312b | |||
| d5e6fb7c54 | |||
| 6138497fe0 | |||
| 05ecac8426 | |||
| 222a1c8a1f | |||
| 04164ff967 | |||
| 9f64692ede | |||
| 8b9ad5d079 | |||
| bff435db9a | |||
| e09a93bd72 | |||
| e378fcfe3b | |||
| a7a338f28e | |||
| a19158cb62 | |||
| 778ed01a55 | |||
| 217f42b7c6 | |||
| a34db6505d | |||
| 7dc117da5e | |||
| b1441366f4 | |||
| c730b85629 | |||
| d3a440fa0a | |||
| 5f77ce619e | |||
| 5dd34c802e | |||
| 3609d94c09 | |||
| 5dc00e95e7 | |||
| e88615226b | |||
| ca1a854fd1 | |||
| ceb5336ca1 | |||
| f651df6e1f | |||
| 6266eac729 | |||
| de972de948 | |||
| 55f48e4f3a | |||
| 39ab07508f | |||
| 968660e8ca | |||
| 4b46ba1fe3 | |||
| a164e6e21e | |||
| 82281b4363 | |||
| 9d8d35b64f | |||
| 33f6a9a213 | |||
| e5ed1d6ae8 | |||
| 9e6a5b2d37 | |||
| c85a724fec | |||
| 2e8f4d1a26 | |||
| 522b57ade4 | |||
| d4da6aa518 | |||
| 979ef907fe | |||
| b2d92b85a0 | |||
| 8d6d0ddbf8 | |||
| 8da76134ce | |||
| 179daf743e | |||
| bcb009b606 | |||
| 327c215e5d | |||
| b484071818 | |||
| 31e826d893 | |||
| e29f912358 | |||
| 26226de865 | |||
| 56d87c4410 | |||
| ebfa5f7405 | |||
| ba16cf41fe | |||
| 01c10bad0e | |||
| 7d1fb3c04e | |||
| 9e222f5b80 | |||
| 3b5658ff8f | |||
| 5e89c4004a | |||
| 9602c28d96 | |||
| 0fd680b496 | |||
| 37d3a44b24 | |||
| da2dec447b | |||
| c6c50a5d23 | |||
| 98c1e8daad | |||
| f99191aa6f | |||
| df04075f1c | |||
| 3d2a635e34 | |||
| aad5db9a6a | |||
| 43ebbdaa33 | |||
| 92c7f90b95 | |||
| aae93d018b | |||
| 7a115a3970 | |||
| 64e5114947 | |||
| 4f8b5e649a | |||
| e0d9989d74 | |||
| 0fe680ef4a | |||
| e182c0a21b | |||
| c8edd241d5 | |||
| a544ccd1a7 | |||
| 7df2205b40 | |||
| 265e843d02 | |||
| 22a8a97389 | |||
| bb74f2a423 | |||
| 2033168db2 | |||
| e377f144fd | |||
| 234ebf8ce8 | |||
| 09cf3c9fa9 | |||
| df32899581 | |||
| 33e8df11c5 | |||
| 75daf37bbd | |||
| d0d2cfb22c | |||
| f7b5ac0dc8 | |||
| 227dd923d6 | |||
| f6cb9a8aed | |||
| b615dc7e6e | |||
| 944560dd2b | |||
| 1d6d29e24d | |||
| ff8e9e6b32 | |||
| 557555c4b3 | |||
| f8e1037476 | |||
| 35cb54324f | |||
| 119497bb01 | |||
| dfd6475a81 | |||
| d6d5236a03 | |||
| a327a26bd5 | |||
| d5ebb7ca12 | |||
| 3e46c5674c | |||
| c4b5565995 | |||
| 3f5eabeaa1 | |||
| 9b8e48e7b2 | |||
| c3122fb82f | |||
| 1741597d52 | |||
| 9c5c74ba84 | |||
| 26ed7b80be | |||
| 55ac9a61ed | |||
| 7673264fe1 | |||
| 42dc43b036 | |||
| ef22d951a0 | |||
| e95dc834a3 | |||
| b424988d1b | |||
| 22134b6cc0 | |||
| f861c0761e | |||
| 1899d5ee17 | |||
| 17bd48ece3 | |||
| c5c02d7f44 | |||
| ba6159964b | |||
| b834971f5e | |||
| 9dc15d536c | |||
| 2e45cb6ac9 | |||
| 2dcfeaa688 | |||
| 9d65d931d0 | |||
| 746aa41111 | |||
| 175dd17416 | |||
| 619936c12e | |||
| 732144df01 | |||
| df3f04a951 | |||
| 0f78968579 | |||
| 66173c7a31 | |||
| 3f934d9aec | |||
| df0cc131fe | |||
| ba60f9da8a | |||
| 4569198b9d | |||
| ccbbb59af7 | |||
| 3a5af25eaf | |||
| 1d18b7fa12 | |||
| 472490c239 | |||
| b6340a30d2 | |||
| bf1f0954b9 | |||
| 2f1cdcf379 | |||
| 443c2023d9 | |||
| 2c5062ba22 | |||
| 99df807095 | |||
| 8ab07d11b1 | |||
| a1c0f6f7f0 | |||
| 672737a0d8 | |||
| ade96bf6d3 | |||
| 801fc062ef | |||
| f35840e7de | |||
| 79eda7abb0 | |||
| e7c7324058 | |||
| d8c1a81bcb | |||
| 94f96c11cb | |||
| ec94dff7d7 | |||
| ebd791a256 | |||
| 4db421d6c3 | |||
| ab89ffe096 | |||
| 53fe5c35b9 | |||
| f2f2c851df | |||
| 6dddc5e948 | |||
| 9688b1a26a | |||
| 81df52f6ca | |||
| 6e4f8f5191 | |||
| 22de3322ae | |||
| e6fae4598c | |||
| ba331dea4a | |||
| 1292a56d1b | |||
| 6a452ffed0 | |||
| fc24570062 | |||
| aa71abd725 | |||
| fb64f5e456 | |||
| 61fe6ea219 | |||
| d30c7254eb | |||
| 06be33ba5f | |||
| b2cffa39e1 | |||
| 86ef2529b1 | |||
| f1b9d1b870 | |||
| fe67b5d72a | |||
| 27720afaf2 | |||
| 8bb585d97d | |||
| 8c523ce8b9 | |||
| e48a28a5c8 | |||
| d66a36cf21 | |||
| a94e09f0aa | |||
| 4df10de6b7 | |||
| 6d07535dad | |||
| ee354d2ded | |||
| e64bd1fba8 | |||
| 031e673c51 | |||
| 801c9a2cda | |||
| 685b3ca5ee | |||
| f1af7e2eeb | |||
| 85f9fda984 | |||
| bb513b0187 | |||
| 4277f90bad | |||
| ccda2bc2fd | |||
| 4b71530f4c | |||
| a8a9db53be | |||
| 634cf07d44 | |||
| 0e0c006d5a | |||
| 486067a4b2 | |||
| 35e10ed469 | |||
| 00b980e74b | |||
| efdc0e7c97 | |||
| 8b64d2066f | |||
| 8d87d9a875 | |||
| 8fc1848ecc | |||
| bbc0a67153 | |||
| e8ba2a7bd1 | |||
| 23f1c112a4 | |||
| 4d76e53554 | |||
| 73352e680e | |||
| 57aad8b454 | |||
| ab5c44a2cb | |||
| 3e84eb9dbf | |||
| afbe82e9f4 | |||
| 51b1aed483 | |||
| 32e93a04c5 | |||
| 3d7ece15f8 | |||
| 541597f355 | |||
| 5fe843d76b | |||
| 3191369ece | |||
| a4de11d69c | |||
| 4832c7db4b | |||
| be83d62f96 | |||
| 3fd2ef1da4 | |||
| d861384889 | |||
| cfd8e88e57 | |||
| 8169cb5a7e | |||
| 8c85cd7346 | |||
| 4e202833b2 | |||
| 4a163bd170 | |||
| 85fbc1b882 | |||
| 61810ff6f9 | |||
| 3a4a29f56d | |||
| 1fb7ece1b3 | |||
| f3879dd3a4 | |||
| 561014886f | |||
| a2b19547a3 | |||
| 93477091d1 | |||
| 64d3c62945 | |||
| 134e27f70a | |||
| 5205aa089b | |||
| b5b9655c1e | |||
| 173d0894fa | |||
| de6b050fb5 | |||
| 37da5e81c5 | |||
| ae8637d455 | |||
| 22a45697fa | |||
| 55462fca9f | |||
| 2799a66c16 | |||
| 9832b17fc2 | |||
| 8146f42492 | |||
| 9df146af3b | |||
| a7629f638f | |||
| e75918f5ed | |||
| 9698c25bc4 | |||
| bbe2bd48d8 | |||
| 0cc565ae80 | |||
| aa74d96fed | |||
| ac6ede6aef | |||
| 10e291bb39 | |||
| 7a25e333db | |||
| a9b9d0badf | |||
| a69e160f85 | |||
| 56d53a455d | |||
| 572afd360a | |||
| ec6f946b97 | |||
| acfd87e548 | |||
| aa228732e3 | |||
| 840c222190 | |||
| 4408957770 | |||
| 89814cbc2e | |||
| fdcefae264 | |||
| 0139919d14 | |||
| 9476bcc7b6 | |||
| 4625451c85 | |||
| 1e345f5010 | |||
| 31befcba44 | |||
| f6077da614 | |||
| 499db7e3eb | |||
| 50da49a3ed | |||
| 6afd5c637e | |||
| 31a6aac9d3 | |||
| 3c3660914f | |||
| cd0ae231dc | |||
| a8bc741883 | |||
| 05b3525863 | |||
| 337f563bd4 | |||
| c9fe09ebe3 | |||
| db1c63a350 | |||
| 7cc2dcd1fc | |||
| bcde392ce3 | |||
| 8d046f6280 | |||
| 9a6696699f | |||
| 56f2eec597 | |||
| d29b33532d | |||
| a16e82bf54 | |||
| 46c17cc441 | |||
| 2099092e16 | |||
| 88b7517337 | |||
| 619236329c | |||
| 76160a5ba6 | |||
| e95f32231a | |||
| be81307faa | |||
| 177e58da4e | |||
| 4c2efc08fd | |||
| ae03922491 | |||
| ab005118ba | |||
| eec8635af4 | |||
| 5060997d2a | |||
| 0ac5a21a14 | |||
| def0f8d144 | |||
| 8895f0dcac | |||
| 4f8db81c85 | |||
| aa388e248d | |||
| e5d7403c54 | |||
| 4f57d6134c | |||
| 03f6b54a5b | |||
| 63ef007ca1 | |||
| 603e0679e7 | |||
| b90445de4a | |||
| 491dd27ebf | |||
| 89d303f375 | |||
| a2ffc1e81c | |||
| a7c47140ae | |||
| ebd7f85fdb | |||
| 833c04776f | |||
| 919c2f62f5 | |||
| 8f6004d444 | |||
| 1b8f5dc673 | |||
| 027a8ec428 | |||
| d1e7765e98 | |||
| 2d1b2e6b6e | |||
| 350fc551e5 | |||
| 1c05c31721 | |||
| 08123fe6ac | |||
| 35b93b1655 | |||
| 436a198c36 | |||
| aa58faf145 | |||
| dcc6d35cba | |||
| 3f29cdc01e | |||
| ba7d55b7c1 | |||
| 6252a0e732 | |||
| ca14b1a427 | |||
| b01db89942 | |||
| fd421c54e3 | |||
| 55992b5066 | |||
| a5dfc9974f | |||
| 7b4a17c934 | |||
| c2a1097dd5 | |||
| ccf78dcb02 | |||
| 3eff400d88 | |||
| 5ab816b5be | |||
| e57840faed | |||
| 240bf4dc5d | |||
| abd1500f07 | |||
| 42144bb31c | |||
| 7ed41a03ae | |||
| 1286ceeddf | |||
| 145efe937c | |||
| ed5adb3f23 | |||
| 7d0508961e | |||
| e53e2e6af9 | |||
| 4fafd2a478 | |||
| f15da4d049 | |||
| 057607f9e5 | |||
| c433b3fd41 | |||
| 632b49ab90 | |||
| f54df8d600 | |||
| d8451ceaa0 | |||
| 62f178c2ee | |||
| eb4e7343e7 | |||
| 5274e8e8ff | |||
| ae2a885d6c | |||
| 901663b145 | |||
| dc301d4c50 | |||
| 34f0535a26 | |||
| af0e2a778d | |||
| 904f1e70f2 | |||
| ddf7ef30ad | |||
| 0a43870e76 | |||
| f875bd2944 | |||
| c9bf20201b | |||
| 76314aab10 | |||
| 3547d326b8 | |||
| 0ecb2ac70e | |||
| 8f8defe0de | |||
| db5572e864 | |||
| 1100cf75d7 | |||
| 4fda06b547 | |||
| fb18b2238e | |||
| 5266a7e4e5 | |||
| 8196fb77d1 | |||
| 4abf6642f7 | |||
| e3284dcfbc | |||
| f064ff6b3d | |||
| bfa5d8cc05 | |||
| 6614919c13 | |||
| 8379acdb7f | |||
| 160ddc258d | |||
| 01892d2766 | |||
| 222955a2e7 | |||
| 37b22c3559 | |||
| afbd522362 | |||
| a4bed3ab14 | |||
| 7468e7a36c | |||
| 145445c713 | |||
| 7fa9314c6b | |||
| 5d37b6c6ae | |||
| fe1f84e29d | |||
| 83e27a6653 | |||
| ee9c68b04e | |||
| c04874397b | |||
| 375604edd6 | |||
| 3e32f3784f | |||
| 5c4a54d998 | |||
| 3af3ac3f6f | |||
| d801f53154 | |||
| a6b06f82e9 | |||
| b7f3f84080 | |||
| 26715bdd4c | |||
| 083fa7857f | |||
| 9ffda3e070 | |||
| 81160dbbe9 | |||
| 7c266b85e2 | |||
| 48cdca7549 | |||
| 1c401eae3b | |||
| 0e9eb30b5d | |||
| c10c9393c0 | |||
| 8705b3437c | |||
| aed891764a | |||
| 495499d12f | |||
| 8d9a021eab | |||
| be6e09c5af | |||
| 293e426ed4 | |||
| 60f2337b73 | |||
| ce8152de2f | |||
| 496a1979d2 | |||
| fd698ca7b9 | |||
| b4b368d324 | |||
| 825694c880 | |||
| 32750a7d50 | |||
| 0045c6c72c | |||
| 4809016b78 | |||
| 6e2ba65524 | |||
| 8033ac66c4 | |||
| 9ef3736989 | |||
| 099dd55d0c | |||
| 53b4175d00 | |||
| 8aa6f08e08 | |||
| c5024598cb | |||
| dfcf6b29c0 | |||
| 7f48d1eb2e | |||
| eaa97995d2 | |||
| 14f997b844 | |||
| 26e87b20b1 | |||
| 5cdf6eff36 | |||
| 4ed535a3b7 | |||
| da15323c2f | |||
| bd1f717b4c | |||
| 72013046fc | |||
| 14ae19143f | |||
| d8260d8383 | |||
| 9174555ff8 | |||
| 0c6ddc2218 | |||
| 43b4075b16 | |||
| 8f8e44fee5 | |||
| 260c12894d | |||
| adf273479a | |||
| 54480da405 | |||
| 90261b2005 | |||
| cc71c225a3 | |||
| e739f30088 | |||
| 51d95b49a0 | |||
| b5c155b927 | |||
| 5a5fe1b0cc | |||
| 1c4e010fc1 | |||
| d8d523d983 | |||
| 1c2589a2f2 | |||
| 1ec61ffa11 | |||
| ca0a5c9cbe | |||
| 8dd31e737f | |||
| e98cca7fbc | |||
| 9830b0a50f | |||
| f76a0ca3e9 | |||
| 5a6d1991ac | |||
| 329e2d8001 | |||
| 403cca5aad | |||
| b8ff5d4cfc | |||
| 54e6c07efc | |||
| d11cda3577 | |||
| abafb80caf | |||
| e0dd85ca99 | |||
| 2c38fe180e | |||
| 0d0f12b394 | |||
| 86d6c96aeb | |||
| b605fb0a77 | |||
| ec773e5f29 | |||
| 9d5d088b4a | |||
| 1b858f5782 | |||
| 5b845f1d03 | |||
| db9d381a43 | |||
| 0df088e1e2 | |||
| 67099d5d06 | |||
| 07e8e0c63c | |||
| ecc89d8596 | |||
| c94b0311b6 | |||
| fc33b4f882 | |||
| 1da1eef768 | |||
| baf10a9ba9 | |||
| bcea4f9464 | |||
| 920290e9dc | |||
| 1d83cf42a1 | |||
| 09bfdf9e77 | |||
| e83fd91423 | |||
| 70421b7bd1 | |||
| 71ae70f670 | |||
| b1b3cea64e | |||
| 2712c57f15 | |||
| 0b528c7225 | |||
| b7007da5a9 | |||
| 489310ba1c | |||
| 6c2c12fe5e | |||
| e61f0db57e | |||
| 3e3546a2fd | |||
| d2fa3b7171 | |||
| 0e9f587591 | |||
| 9208b15167 | |||
| a45fb30e0a | |||
| 97c7edafd6 | |||
| 1a51b1adc7 | |||
| 9d2be5c50d | |||
| f381f24402 | |||
| f6db85fcdb | |||
| 9687d5cd66 | |||
| 6e2d00bc5b | |||
| 5aaab89cd8 | |||
| 7407d24586 | |||
| c9931da5ba | |||
| 4311f06ade | |||
| 8b64b5d372 | |||
| 631ca4f8a3 | |||
| 424618de38 | |||
| b2d3ca9543 | |||
| cb33f20a24 | |||
| 973d804db2 | |||
| 84eaa6b7b6 | |||
| f967a428ce | |||
| 543d464cbc | |||
| 43470b2a41 | |||
| fa05e25a9d | |||
| fe2f1605f1 | |||
| 48b5c167bf | |||
| 08a0a36dfd | |||
| d135c31ca0 | |||
| dce68221ad | |||
| 93273bd470 | |||
| 92f7c11999 | |||
| 024ce8e73c | |||
| 7902389ef1 | |||
| 1e9ab2f805 | |||
| 0550212b64 | |||
| c7b6ca67a2 | |||
| 9dae2de2fa | |||
| 968593106e | |||
| 302cb0130d | |||
| 89efaa790f | |||
| 60f0e62c23 | |||
| f113e2ef31 | |||
| 39923d6617 | |||
| 72be443414 | |||
| 392e8060ba | |||
| 8c01b0f6c0 | |||
| b984475e49 | |||
| 4f114ea33c | |||
| 5b8a9c0108 | |||
| ee6500ac65 | |||
| 3b2a1c3f25 | |||
| 4d87359aca | |||
| c37c1ff812 | |||
| 1812a2e9ad | |||
| ccc02f41bf | |||
| eaf10c70b7 | |||
| 06f42dd9cb | |||
| 1d6ff73aad | |||
| 700a6fe643 | |||
| 0a7432b059 | |||
| b369fda1d9 | |||
| c49c35cfbd | |||
| fb4742e165 | |||
| fce45b93a2 | |||
| 18ecd46a01 | |||
| af8fbdae72 | |||
| c84997be30 | |||
| 06551d6084 | |||
| 84145d7cc8 | |||
| 426beae796 | |||
| aadf12c7b3 | |||
| 1b60935d08 | |||
| d68731fd55 | |||
| ba63c8c661 | |||
| 15487b347f | |||
| e7e90c6527 | |||
| ca5421347a | |||
| c8a57f2046 | |||
| 583df13139 | |||
| 5049961e17 | |||
| 18492e5d61 | |||
| d4d9f89d1d | |||
| ecf19034ae | |||
| 00521c490e | |||
| 3071df227a | |||
| 915cabdf97 | |||
| 61ac29b2de | |||
| ab84a5169e | |||
| 3fad25b8c8 | |||
| 8154c403d8 | |||
| bb83aed20d | |||
| 600c9fc907 | |||
| 5d09eb149c | |||
| e854fe3681 | |||
| 36c8822e6c | |||
| 9b29cce1a4 | |||
| 508f06339e | |||
| 0a9cdd2f15 | |||
| 7f77b6e3ec | |||
| 9507b0b1ba | |||
| ad9d6f4301 | |||
| b721fb6860 | |||
| 5f46cd2ea5 | |||
| 35efed9fef | |||
| 08e53919e2 | |||
| 933c8841ff | |||
| 518281e101 | |||
| 515d4bab0d | |||
| 8e72a820dd | |||
| f1f0fa34cb | |||
| 5010ef93e8 | |||
| e6679a3192 | |||
| 7cf8d5d2d3 | |||
| 14198eca41 | |||
| c6473f20dc | |||
| 9c34cb5862 | |||
| 149fd1629f | |||
| c48241f78a | |||
| a1bee81a5b | |||
| 1b053c03ba | |||
| 33057acd62 | |||
| 07511a2eb0 | |||
| 69c634d53f | |||
| 7bc17a9202 | |||
| d94a08b991 | |||
| a8b8c1feec | |||
| a589e5a090 | |||
| 8b1db3304f | |||
| 23aedd68b0 | |||
| f48f08a98b | |||
| 81dd88d25a | |||
| c92081d6e1 | |||
| d6e80f5a23 | |||
| 37cf71234c | |||
| 3b655f39e1 | |||
| eec0ddf466 | |||
| ca4e53bb0f | |||
| d9f2e91806 | |||
| 7bfed62526 | |||
| b63ac98f40 | |||
| 1e7d297c0e | |||
| f3cd3b88b9 | |||
| 9a199cd834 | |||
| c3fac2e83f | |||
| c7f6d2727c | |||
| 9901c63ede | |||
| 76897b8a83 | |||
| 217cf1420b | |||
| 6897192364 | |||
| 031ace3fe5 | |||
| e4683b9a05 | |||
| 93da32cfb3 | |||
| 62a0e52092 | |||
| 262ba10443 | |||
| 50cb88c5ed | |||
| 76e32703ac | |||
| d9f5fbaf04 | |||
| 16bb238518 | |||
| 759135fd7d | |||
| 56075857f2 | |||
| 8d3c7500d8 | |||
| 1e3f5e8695 | |||
| 08f5865c72 | |||
| ff3c141138 | |||
| fe31e0e849 | |||
| 2a26968c6c | |||
| fe8774953a | |||
| 4a7f036561 | |||
| 612f260938 | |||
| 2ad666d221 | |||
| aff4cc516e | |||
| 6fbcffe63b | |||
| ebd868fa33 | |||
| 71a63cc70e | |||
| 3702efc5be | |||
| 16e51cd4e5 | |||
| 87747fab06 | |||
| 4fe3d4339f | |||
| a276fb6b79 | |||
| fa8d8f9ea0 | |||
| c58031cbf4 | |||
| 4aae12fc63 | |||
| 256a8fb5c5 | |||
| 3c5a7cd664 | |||
| 796985472a | |||
| 7e0014865e | |||
| cd74d1887a | |||
| adf36e71ce | |||
| fc3c303d30 | |||
| 0e50977779 | |||
| ed9feaf542 | |||
| 09d427b4ba | |||
| 5dac8af300 | |||
| 1493a6180a | |||
| 848ddcebd7 | |||
| 71763d340e | |||
| 89daf6489d | |||
| 356e93914b | |||
| 5523d0c27a | |||
| 590a94523e | |||
| 3c95b84633 | |||
| 59943c87cd | |||
| 3f9a46b1f7 | |||
| 81faca041a | |||
| 60fccea703 | |||
| 118bf1fc65 | |||
| ce7ae3edd4 | |||
| 717eb526fb | |||
| 9241fddb1e | |||
| 2dff0bed72 | |||
| 4827c116f0 | |||
| 848afac803 | |||
| 13b0204427 | |||
| dc5f002de3 | |||
| 2ca44ec361 | |||
| c62d48160a | |||
| 9129f1b82a | |||
| 378cfc0c3d | |||
| 7db71d43e0 | |||
| 85b678a8fb | |||
| 9902ce2b78 | |||
| 394c7b22a2 | |||
| f99c993d96 | |||
| 1eb42446f8 | |||
| 3d001e7458 | |||
| 2dd3fc7df8 | |||
| f46677dfc0 | |||
| e94ccc86f8 | |||
| e778903dab | |||
| a1ea298a43 | |||
| 7a4a8e0fe2 | |||
| bbaefd0f77 | |||
| 951d0e8653 | |||
| 7d73d048c8 | |||
| a48766871d | |||
| 406cb4a619 | |||
| 9418cc7a69 | |||
| 20f6fbcf84 | |||
| 327f18525c | |||
| 8a0ea59c77 | |||
| f6ad846927 | |||
| 114b5724f8 | |||
| 3e328932fc | |||
| fac60a197b | |||
| 55cd813141 | |||
| 86f28faf8d | |||
| 023faa66fc | |||
| 3462cdf827 | |||
| 8aab988752 |
@@ -0,0 +1,21 @@
|
|||||||
|
# EditorConfig
|
||||||
|
# https://editorconfig.org/
|
||||||
|
# https://editorconfig-specification.readthedocs.io/
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# Unix-style newlines with a newline ending every file
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
# 4 space indentation
|
||||||
|
[*.{h,cpp,html,css,js,conf,txt}]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
# Tab indentation (no size specified)
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
.cproject
|
||||||
|
.project
|
||||||
|
.settings/
|
||||||
|
*.o
|
||||||
|
*.so
|
||||||
|
/winixd/winix
|
||||||
|
/winixcli/src/winix
|
||||||
|
/winixcli/m
|
||||||
|
/.clangd
|
||||||
|
/.qtcreator/
|
||||||
|
/.qtc_clangd/
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
CompileFlags:
|
||||||
|
Add: [-pthread, -std=c++20, -I%%%CURRENT_DIR%%%/winixd, -I%%%GLOBAL_WORKING_DIR%%%/pikotools/src, -I%%%GLOBAL_WORKING_DIR%%%/ezc/src, -I%%%GLOBAL_WORKING_DIR%%%/morm/src, -I%%%GLOBAL_WORKING_DIR%%%/tito/src, -I/usr/include, -I/usr/local/include, -I/usr/local/include/postgresql, -DPT_HAS_MORM_LIBRARY, -DEZC_HAS_MORM_LIBRARY, -DMORM_HAS_EZC_LIBRARY]
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
-std=c20
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#define PT_HAS_MORM_LIBRARY 1
|
||||||
|
#define EZC_HAS_MORM_LIBRARY 1
|
||||||
|
#define MORM_HAS_EZC_LIBRARY 1
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[General]
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE QtCreatorProject>
|
||||||
|
<!-- Written by QtCreator 14.0.1, 2024-09-20T16:21:10. -->
|
||||||
|
<qtcreator>
|
||||||
|
<data>
|
||||||
|
<variable>EnvironmentId</variable>
|
||||||
|
<value type="QByteArray">%%%QT_ENVIRONMENT_ID%%%</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||||
|
<value type="qlonglong">0</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||||
|
<value type="QString" key="language">Cpp</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||||
|
<value type="QString" key="language">QmlJS</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||||
|
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||||
|
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.Utf8BomBehavior">2</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||||
|
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
|
||||||
|
<value type="bool" key="AutoTest.Framework.Boost">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.CTest">false</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.Catch">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.GTest">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="bool" key="AutoTest.ApplyFilter">false</value>
|
||||||
|
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
|
||||||
|
<valuelist type="QVariantList" key="AutoTest.PathFilters"/>
|
||||||
|
<value type="int" key="AutoTest.RunAfterBuild">0</value>
|
||||||
|
<value type="bool" key="AutoTest.UseGlobal">true</value>
|
||||||
|
<valuemap type="QVariantMap" key="ClangTools">
|
||||||
|
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
|
||||||
|
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
|
||||||
|
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
|
||||||
|
<value type="int" key="ClangTools.ParallelJobs">3</value>
|
||||||
|
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
||||||
|
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="QString" key="DeviceType">Desktop</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">%%%QT_DEFAULT_PROFILE_ID%%%</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">%%%CURRENT_DIR%%%</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
|
||||||
|
<value type="QString">all</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand">/usr/local/bin/gmake</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
|
||||||
|
<value type="QString">clean</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand">/usr/local/bin/gmake</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Default</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||||
|
<value type="qlonglong">1</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||||
|
<value type="int">22</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>Version</variable>
|
||||||
|
<value type="int">22</value>
|
||||||
|
</data>
|
||||||
|
</qtcreator>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
-std=c++20
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
Executable
+30
@@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
CURRENT_DIR=$(pwd)
|
||||||
|
GLOBAL_WORKING_DIR=$(realpath ${CURRENT_DIR}/..)
|
||||||
|
|
||||||
|
# ----------
|
||||||
|
|
||||||
|
# make sure the current directory is correct
|
||||||
|
if [ ! -d ${CURRENT_DIR}/.templates ] ; then
|
||||||
|
echo "this script should be called by make: make clangd (one level up)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# change / to \/ in paths
|
||||||
|
CURRENT_DIR_FOR_SED=$(echo ${CURRENT_DIR} | sed 's/\//\\\//g')
|
||||||
|
GLOBAL_WORKING_DIR_FOR_SED=$(echo ${GLOBAL_WORKING_DIR} | sed 's/\//\\\//g')
|
||||||
|
|
||||||
|
|
||||||
|
if [ -f "${CURRENT_DIR}/.templates/.clangd" ] ; then
|
||||||
|
if [ ! -f "${CURRENT_DIR}/.clangd" ] ; then
|
||||||
|
cat "${CURRENT_DIR}/.templates/.clangd" | \
|
||||||
|
sed -e "s/%%%CURRENT_DIR%%%/${CURRENT_DIR_FOR_SED}/g" \
|
||||||
|
-e "s/%%%GLOBAL_WORKING_DIR%%%/${GLOBAL_WORKING_DIR_FOR_SED}/g" > \
|
||||||
|
${CURRENT_DIR}/.clangd
|
||||||
|
|
||||||
|
echo "added a ${CURRENT_DIR}/.clangd file"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
Executable
+105
@@ -0,0 +1,105 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
CURRENT_DIR=$(pwd)
|
||||||
|
GLOBAL_WORKING_DIR=$(realpath ${CURRENT_DIR}/..)
|
||||||
|
QTCREATOR_DIR=${CURRENT_DIR}/.qtcreator
|
||||||
|
|
||||||
|
# ----------
|
||||||
|
|
||||||
|
# make sure the current directory is correct
|
||||||
|
if [ ! -d ${CURRENT_DIR}/.templates ] ; then
|
||||||
|
echo "this script should be called by make: make qtcreator (one level up)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
qtcreatorini=~/.config/QtProject/QtCreator.ini
|
||||||
|
qtprofiles=~/.config/QtProject/qtcreator/profiles.xml
|
||||||
|
|
||||||
|
if [ ! -f "$qtcreatorini" ] ; then
|
||||||
|
echo "I cannot find a $qtcreatorini file"
|
||||||
|
echo "this file is needed to take an EnvironmentId parameter"
|
||||||
|
echo "if QTCreator was recently installed make sure you have opened it at least once"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$qtprofiles" ] ; then
|
||||||
|
echo "I cannot find a $qtprofiles file"
|
||||||
|
echo "this file is needed to take a default profile id parameter"
|
||||||
|
echo "if QTCreator was recently installed make sure you have opened it at least once"
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
qtenvironmentid=`grep -F 'Settings\EnvironmentId' "$qtcreatorini" | grep -Eo '\{[a-zA-Z0-9-]+\}'`
|
||||||
|
qtdefaultprofileid=`grep -A 1 -F '<variable>Profile.Default</variable>' "$qtprofiles" | tail -n 1 | grep -Eo '\{[a-zA-Z0-9-]+\}'`
|
||||||
|
|
||||||
|
if [ -z "$qtenvironmentid" ] ; then
|
||||||
|
echo "I cannot read a Settings\EnvironmentId parameter from $qtcreatorini file"
|
||||||
|
exit 4
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$qtdefaultprofileid" ] ; then
|
||||||
|
echo "I cannot read a Profile.Default parameter from $qtprofiles file"
|
||||||
|
exit 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
# change / to \/ in paths
|
||||||
|
CURRENT_DIR_FOR_SED=$(echo ${CURRENT_DIR} | sed 's/\//\\\//g')
|
||||||
|
GLOBAL_WORKING_DIR_FOR_SED=$(echo ${GLOBAL_WORKING_DIR} | sed 's/\//\\\//g')
|
||||||
|
|
||||||
|
was_qtcreator_dir=0
|
||||||
|
|
||||||
|
if [ -d "${QTCREATOR_DIR}" ] ; then
|
||||||
|
was_qtcreator_dir=1
|
||||||
|
else
|
||||||
|
echo "Your QTCreator EnvironmentId is: $qtenvironmentid"
|
||||||
|
echo "Your QTCreator default profile id is: $qtdefaultprofileid"
|
||||||
|
mkdir -p "${QTCREATOR_DIR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d "${QTCREATOR_DIR}" ] ; then
|
||||||
|
|
||||||
|
if [ -d ${CURRENT_DIR}/.templates/.qtcreator ] ; then
|
||||||
|
cd ${CURRENT_DIR}/.templates/.qtcreator
|
||||||
|
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
|
||||||
|
for i in * ; do
|
||||||
|
if [ ! -f "${QTCREATOR_DIR}/$i" ] ; then
|
||||||
|
cat "$i" | \
|
||||||
|
sed -e "s/%%%CURRENT_DIR%%%/${CURRENT_DIR_FOR_SED}/g" \
|
||||||
|
-e "s/%%%GLOBAL_WORKING_DIR%%%/${GLOBAL_WORKING_DIR_FOR_SED}/g" \
|
||||||
|
-e "s/%%%QT_ENVIRONMENT_ID%%%/${qtenvironmentid}/g" \
|
||||||
|
-e "s/%%%QT_DEFAULT_PROFILE_ID%%%/${qtdefaultprofileid}/g" > \
|
||||||
|
"${QTCREATOR_DIR}/$i"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $was_qtcreator_dir -eq 0 ] ; then
|
||||||
|
echo "QTCreator files generated to ${QTCREATOR_DIR} directory"
|
||||||
|
echo "select an 'open project...' option and find a ${QTCREATOR_DIR}/*.creator file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
find ${QTCREATOR_DIR} -name "*.files" | while read projectfiles ; do
|
||||||
|
|
||||||
|
cd ${CURRENT_DIR}/winixd
|
||||||
|
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
find ../winixd -type f \( -iname "*.cpp" -o -iname "*.h" \) | sort > ${projectfiles}
|
||||||
|
echo "file ${projectfiles} has been updated"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ${CURRENT_DIR}/winixcli
|
||||||
|
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
find ../winixcli -type f \( -iname "*.cpp" -o -iname "*.h" \) | sort >> ${projectfiles}
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
Copyright (c) 2012-2026, Tomasz Sowa
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
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.
|
||||||
@@ -1,46 +1,62 @@
|
|||||||
CC = g++
|
|
||||||
o = templates.o log.o requestcontroller.o main.o misc.o db.o session.o request.o content.o sessionmanager.o httpsimpleparser.o data.o dir.o error.o done.o dircontainer.o ezc.o
|
|
||||||
CFLAGS = -Wall -pedantic -g -I/usr/local/include -L/usr/local/lib
|
|
||||||
name = cmslu.fcgi
|
|
||||||
|
|
||||||
|
|
||||||
all: $(name) $(mod_cms)
|
export CXX
|
||||||
|
export CXXFLAGS
|
||||||
$(name): $(o)
|
export LDFLAGS
|
||||||
g++ -o $(name) $(CFLAGS) $(o) -lfcgi -lpq
|
|
||||||
|
|
||||||
|
|
||||||
|
all: winixd winixcli
|
||||||
|
|
||||||
|
|
||||||
.SUFFIXES: .cpp .o
|
winixd: FORCE
|
||||||
|
$(MAKE) -C winixd
|
||||||
.cpp.o:
|
|
||||||
$(CC) -c $(CFLAGS) $<
|
|
||||||
|
|
||||||
|
|
||||||
|
winixcli: FORCE
|
||||||
templates.o: core/templates.cpp core/templates.h core/../../ezc/src/ezc.h core/data.h core/misc.h core/log.h core/item.h core/error.h core/dir.h core/db.h core/dircontainer.h core/request.h core/requesttypes.h core/session.h core/done.h core/getparser.h core/httpsimpleparser.h core/postparser.h core/cookieparser.h
|
$(MAKE) -C winixcli
|
||||||
log.o: core/log.cpp core/log.h
|
|
||||||
requestcontroller.o: core/requestcontroller.cpp core/requestcontroller.h core/data.h core/misc.h core/log.h core/item.h core/error.h core/dir.h core/db.h core/dircontainer.h core/request.h core/requesttypes.h core/session.h core/done.h core/getparser.h core/httpsimpleparser.h core/postparser.h core/cookieparser.h core/content.h core/templates.h core/../../ezc/src/ezc.h core/sessionmanager.h
|
|
||||||
main.o: core/main.cpp core/requestcontroller.h core/data.h core/misc.h core/log.h core/item.h core/error.h core/dir.h core/db.h core/dircontainer.h core/request.h core/requesttypes.h core/session.h core/done.h core/getparser.h core/httpsimpleparser.h core/postparser.h core/cookieparser.h core/content.h core/templates.h core/../../ezc/src/ezc.h core/sessionmanager.h
|
|
||||||
misc.o: core/misc.cpp core/misc.h core/log.h core/item.h
|
|
||||||
db.o: core/db.cpp core/db.h core/log.h core/item.h core/misc.h core/error.h core/dircontainer.h
|
|
||||||
session.o: core/session.cpp core/session.h core/requesttypes.h core/error.h core/log.h core/item.h core/done.h
|
|
||||||
request.o: core/request.cpp core/request.h core/requesttypes.h core/log.h core/session.h core/error.h core/item.h core/done.h core/getparser.h core/httpsimpleparser.h core/postparser.h core/cookieparser.h
|
|
||||||
content.o: core/content.cpp core/content.h core/templates.h core/../../ezc/src/ezc.h core/data.h core/misc.h core/log.h core/item.h core/error.h core/dir.h core/db.h core/dircontainer.h core/request.h core/requesttypes.h core/session.h core/done.h core/getparser.h core/httpsimpleparser.h core/postparser.h core/cookieparser.h
|
|
||||||
sessionmanager.o: core/sessionmanager.cpp core/sessionmanager.h core/request.h core/requesttypes.h core/log.h core/session.h core/error.h core/item.h core/done.h core/getparser.h core/httpsimpleparser.h core/postparser.h core/cookieparser.h core/data.h core/misc.h core/dir.h core/db.h core/dircontainer.h
|
|
||||||
httpsimpleparser.o: core/httpsimpleparser.cpp core/httpsimpleparser.h
|
|
||||||
data.o: core/data.cpp core/data.h core/misc.h core/log.h core/item.h core/error.h core/dir.h core/db.h core/dircontainer.h
|
|
||||||
dir.o: core/dir.cpp core/dir.h core/item.h core/error.h core/log.h core/db.h core/misc.h core/dircontainer.h
|
|
||||||
error.o: core/error.cpp core/error.h core/log.h
|
|
||||||
done.o: core/done.cpp core/done.h
|
|
||||||
dircontainer.o: core/dircontainer.cpp core/dircontainer.h core/item.h core/log.h
|
|
||||||
|
|
||||||
ezc.o: ../ezc/src/ezc.cpp ../ezc/src/ezc.h
|
|
||||||
|
|
||||||
|
|
||||||
|
clean: FORCE
|
||||||
|
$(MAKE) -C winixd clean
|
||||||
|
$(MAKE) -C winixcli clean
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.o
|
cleanall: FORCE
|
||||||
rm -f $(name)
|
$(MAKE) -C winixd cleanall
|
||||||
|
$(MAKE) -C winixcli clean
|
||||||
|
|
||||||
|
|
||||||
|
depend: FORCE
|
||||||
|
$(MAKE) -C winixd depend
|
||||||
|
$(MAKE) -C winixcli depend
|
||||||
|
|
||||||
|
|
||||||
|
install: FORCE
|
||||||
|
$(MAKE) -C winixd install
|
||||||
|
#$(MAKE) -C winixcli depend
|
||||||
|
|
||||||
|
|
||||||
|
clangd: FORCE
|
||||||
|
@.templates/install_clangd.sh
|
||||||
|
|
||||||
|
|
||||||
|
clangdall: clangd
|
||||||
|
@$(MAKE) -C ../pikotools clangd
|
||||||
|
@$(MAKE) -C ../morm clangd
|
||||||
|
@$(MAKE) -C ../ezc clangd
|
||||||
|
@$(MAKE) -C ../tito clangd
|
||||||
|
|
||||||
|
|
||||||
|
qtcreator: clangd
|
||||||
|
@.templates/install_qtcreator.sh
|
||||||
|
|
||||||
|
|
||||||
|
qtcreatorall: qtcreator
|
||||||
|
@$(MAKE) -C ../pikotools qtcreator
|
||||||
|
@$(MAKE) -C ../morm qtcreator
|
||||||
|
@$(MAKE) -C ../ezc qtcreator
|
||||||
|
@$(MAKE) -C ../tito qtcreator
|
||||||
|
|
||||||
|
|
||||||
|
FORCE:
|
||||||
|
|
||||||
|
|||||||
@@ -1,477 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "content.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Content::Init()
|
|
||||||
{
|
|
||||||
templates.Read();
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Content::AddItem()
|
|
||||||
{
|
|
||||||
if( !request.session->is_logged )
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
request.session->done = Done::added_item;
|
|
||||||
|
|
||||||
// request.item_table.resize(1);
|
|
||||||
// Item & item = request.item_table[0];
|
|
||||||
|
|
||||||
request.item.subject = request.PostVar("subject");
|
|
||||||
request.item.content = request.PostVar("content");
|
|
||||||
request.item.parent_id = data.dir.GetDirId( request.PostVar("directory") );
|
|
||||||
request.item.type = Item::file;
|
|
||||||
PrepareUrlSubject(request.item);
|
|
||||||
|
|
||||||
request.session->done_status = db.AddItem(request.item);
|
|
||||||
request.session->done_timer = 1;
|
|
||||||
|
|
||||||
// if( request.session->done_status != Request::added_item )
|
|
||||||
//request.item_table.resize(1);
|
|
||||||
//request.item_table[0] = request.item;
|
|
||||||
}
|
|
||||||
catch(const Error & e)
|
|
||||||
{
|
|
||||||
request.session->done_status = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Content::EditItem()
|
|
||||||
{
|
|
||||||
if( !request.session->is_logged )
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
request.session->done = Done::edited_item;
|
|
||||||
|
|
||||||
// request.item_table.resize(1);
|
|
||||||
// Item & item = request.item_table[0];
|
|
||||||
|
|
||||||
request.item.subject = request.PostVar("subject");
|
|
||||||
request.item.content = request.PostVar("content");
|
|
||||||
request.item.id = atol( request.PostVar("id").c_str() );
|
|
||||||
|
|
||||||
bool with_subject = false;
|
|
||||||
|
|
||||||
if( request.PostVar("old_subject") != request.item.subject )
|
|
||||||
with_subject = true;
|
|
||||||
|
|
||||||
request.item.parent_id = data.dir.GetDirId( request.PostVar("directory") );
|
|
||||||
request.item.type = Item::file;
|
|
||||||
PrepareUrlSubject(request.item);
|
|
||||||
|
|
||||||
request.session->done_status = db.EditItem(request.item, with_subject);
|
|
||||||
request.session->done_timer = 1;
|
|
||||||
}
|
|
||||||
catch(const Error & e)
|
|
||||||
{
|
|
||||||
request.session->done_status = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Content::LogUser()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::string & login = request.PostVar("login");
|
|
||||||
std::string & pass = request.PostVar("password");
|
|
||||||
long user_id;
|
|
||||||
|
|
||||||
if( db.CheckUser(login, pass, user_id) )
|
|
||||||
{
|
|
||||||
request.session->is_logged = true;
|
|
||||||
request.session->user_id = user_id;
|
|
||||||
request.session->user = login;
|
|
||||||
|
|
||||||
log << log2 << "User " << login << " (id: " << user_id << ") logged" << logend;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(const Error &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Content::MakeDirectoryStructure()
|
|
||||||
{
|
|
||||||
GetTable::size_type get_table_len = request.get_table.size();
|
|
||||||
long parent = -1;
|
|
||||||
|
|
||||||
for( get_index = 0 ; get_index < get_table_len ; ++get_index)
|
|
||||||
{
|
|
||||||
Item * pdir;
|
|
||||||
|
|
||||||
if( !data.dir.GetDir(request.get_table[get_index], parent, &pdir) )
|
|
||||||
break;
|
|
||||||
|
|
||||||
parent = pdir->id;
|
|
||||||
request.cur_dir_table.push_back( *pdir );
|
|
||||||
}
|
|
||||||
|
|
||||||
// parent - last directory (or -1 if none)
|
|
||||||
request.dir = parent;
|
|
||||||
data.dir.GetDirChilds(parent, request.dir_table);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Request::Result Content::StandardFunction(std::string & name)
|
|
||||||
{
|
|
||||||
Request::Result res = Request::err404;
|
|
||||||
|
|
||||||
// language polish
|
|
||||||
// in the future there'll be something here
|
|
||||||
// names of functions should not begin with an underscore '_'
|
|
||||||
|
|
||||||
if( name == "dodaj" )
|
|
||||||
res = Request::add_item;
|
|
||||||
else
|
|
||||||
if( name == "edytuj" )
|
|
||||||
res = Request::edit_item;
|
|
||||||
else
|
|
||||||
if( name == "id" )
|
|
||||||
res = Request::show_item_by_id;
|
|
||||||
else
|
|
||||||
if( name == "usun" )
|
|
||||||
res = Request::del_item;
|
|
||||||
else
|
|
||||||
if( name == "potwierdz" )
|
|
||||||
res = Request::confirm;
|
|
||||||
else
|
|
||||||
if( name == "wyloguj" )
|
|
||||||
res = Request::logout;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Content::PrepareUrlSubject(Item & item)
|
|
||||||
{
|
|
||||||
SetUrlSubjectFromSubject(item);
|
|
||||||
|
|
||||||
if( StandardFunction(item.url_subject) != Request::err404 )
|
|
||||||
{
|
|
||||||
// names of functions should not begin with an underscore '_'
|
|
||||||
// and we can simply add one '_' at the beginning
|
|
||||||
// and the name will be unique
|
|
||||||
item.url_subject.insert(item.url_subject.begin(), '_');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Content::MakeGetCheckDir()
|
|
||||||
{
|
|
||||||
if( get_index == request.get_table.size() )
|
|
||||||
{
|
|
||||||
// request was for a directory
|
|
||||||
db.GetItems(request.item_table, item);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// !! temporarily
|
|
||||||
long default_id = -1;
|
|
||||||
if( request.cur_dir_table.empty() )
|
|
||||||
{
|
|
||||||
default_id = data.dir.root.default_item;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
default_id = request.cur_dir_table.back().default_item;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( default_id != -1 )
|
|
||||||
{
|
|
||||||
request.result = Request::show_item;
|
|
||||||
|
|
||||||
std::vector<Item>::iterator i;
|
|
||||||
for(i = request.item_table.begin() ; i != request.item_table.end() ; ++i)
|
|
||||||
{
|
|
||||||
if( i->id == default_id )
|
|
||||||
request.item_table[0] = *i;
|
|
||||||
}
|
|
||||||
|
|
||||||
request.item_table.resize(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
|
|
||||||
if( data.one_item_is_showed &&
|
|
||||||
request.item_table.size() == 1 &&
|
|
||||||
request.item_table[0].type == Item::file )
|
|
||||||
{
|
|
||||||
request.result = Request::show_item;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
request.result = Request::show_dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// zrobic tak ze gdzie podajemy cala liste aby nie ladowac contentu z bazy danych do itemow
|
|
||||||
void Content::MakeGet()
|
|
||||||
{
|
|
||||||
MakeDirectoryStructure();
|
|
||||||
|
|
||||||
item.Clear();
|
|
||||||
|
|
||||||
// request.dir is set by MakeDirectoryStructure()
|
|
||||||
item.parent_id = request.dir;
|
|
||||||
|
|
||||||
if( MakeGetCheckDir() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
// request was for an item or a standard function
|
|
||||||
request.result = StandardFunction( request.get_table[get_index] );
|
|
||||||
|
|
||||||
if( request.result != Request::err404 )
|
|
||||||
{
|
|
||||||
// request for a standard function
|
|
||||||
++get_index;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( request.get_table[get_index].empty() )
|
|
||||||
// we do not have an empty url_subject
|
|
||||||
// err404 at the end
|
|
||||||
return;
|
|
||||||
|
|
||||||
// if we want to search by url_subject then request.get_table[get_index] should not be empty
|
|
||||||
item.url_subject = request.get_table[get_index++];
|
|
||||||
db.GetItems(request.item_table, item);
|
|
||||||
|
|
||||||
if( request.item_table.empty() )
|
|
||||||
// err404 at the end
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( get_index == request.get_table.size() )
|
|
||||||
{
|
|
||||||
request.result = Request::show_item;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// there is a standard function at the end
|
|
||||||
request.result = StandardFunction( request.get_table[get_index++] );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Content::MakeEditItem()
|
|
||||||
{
|
|
||||||
if( !request.item_table.empty() )
|
|
||||||
request.item = request.item_table[0];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log << log1 << "Content: request.item_table should not be empty" << logend;
|
|
||||||
request.result = Request::err404;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Content::AppendCurDir(std::string & dir)
|
|
||||||
{
|
|
||||||
std::vector<Item>::size_type a;
|
|
||||||
|
|
||||||
for(a=0 ; a<request.cur_dir_table.size() ; ++a)
|
|
||||||
{
|
|
||||||
dir += request.cur_dir_table[a].url_subject;
|
|
||||||
dir += '/';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Content::MakeShowItemById()
|
|
||||||
{
|
|
||||||
if( get_index == request.get_table.size() )
|
|
||||||
{
|
|
||||||
request.result = Request::err404;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
long id = atol( request.get_table[get_index++].c_str() );
|
|
||||||
db.GetItem(request.item_table, id);
|
|
||||||
|
|
||||||
if( request.item_table.empty() )
|
|
||||||
request.result = Request::err404;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
request.result = Request::redirect;
|
|
||||||
std::string path;
|
|
||||||
data.dir.MakePath(request.item_table[0].parent_id, path);
|
|
||||||
request.str = data.base_url + path + request.item_table[0].url_subject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Content::MakeDelItem()
|
|
||||||
{
|
|
||||||
if( !request.session->is_logged )
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
if( request.item_table.empty() )
|
|
||||||
{
|
|
||||||
request.result = Request::err404;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( get_index == request.get_table.size() )
|
|
||||||
{
|
|
||||||
request.CopyFirstItem();
|
|
||||||
request.session->item = request.item;
|
|
||||||
|
|
||||||
if( db.DelItem( request.item.id ) )
|
|
||||||
{
|
|
||||||
request.session->done = Done::deleted_item;
|
|
||||||
request.session->done_status = Error::ok;
|
|
||||||
log << log2 << "Content: deleted item: subject: " << request.item.subject << ", id: " << request.item.id << logend;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
request.session->done = Done::deleted_item;
|
|
||||||
request.session->done_status = Error::db_no_item;
|
|
||||||
}
|
|
||||||
|
|
||||||
request.result = Request::redirect;
|
|
||||||
request.str = data.base_url;
|
|
||||||
AppendCurDir(request.str);
|
|
||||||
request.session->done_timer = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( StandardFunction( request.get_table[get_index++] ) == Request::confirm )
|
|
||||||
{
|
|
||||||
request.result = Request::del_item_confirm;
|
|
||||||
request.CopyFirstItem();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
request.result = Request::err404;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Content::MakeLogout()
|
|
||||||
{
|
|
||||||
if( request.session->is_logged )
|
|
||||||
{
|
|
||||||
log << log2 << "User " << request.session->user << " (id: " << request.session->user_id << ") logged out" << logend;
|
|
||||||
|
|
||||||
request.session->is_logged = false;
|
|
||||||
request.session->user.clear();
|
|
||||||
request.session->user_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
request.result = Request::redirect;
|
|
||||||
std::string path;
|
|
||||||
data.dir.MakePath(request.dir, path);
|
|
||||||
request.str = data.base_url + path;
|
|
||||||
|
|
||||||
if( !request.item_table.empty() )
|
|
||||||
request.str += request.item_table[0].url_subject;
|
|
||||||
|
|
||||||
request.session->done = Done::loggedout;
|
|
||||||
request.session->done_timer = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Content::MakeStandardFunction()
|
|
||||||
{
|
|
||||||
if( request.result == Request::edit_item )
|
|
||||||
{
|
|
||||||
MakeEditItem();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( request.result == Request::show_item_by_id )
|
|
||||||
{
|
|
||||||
MakeShowItemById();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( request.result == Request::del_item )
|
|
||||||
{
|
|
||||||
MakeDelItem();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( request.result == Request::logout )
|
|
||||||
{
|
|
||||||
MakeLogout();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Content::MakePost()
|
|
||||||
{
|
|
||||||
if( request.IsPostVar("add_item") )
|
|
||||||
AddItem();
|
|
||||||
else
|
|
||||||
if( request.IsPostVar("edit_item") )
|
|
||||||
EditItem();
|
|
||||||
else
|
|
||||||
if( request.IsPostVar("logging") )
|
|
||||||
LogUser();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Content::Make()
|
|
||||||
{
|
|
||||||
MakePost();
|
|
||||||
MakeGet();
|
|
||||||
MakeStandardFunction();
|
|
||||||
|
|
||||||
templates.Generate();
|
|
||||||
|
|
||||||
// request.PrintGetTable();
|
|
||||||
//request.PrintEnv();
|
|
||||||
// request.PrintIn();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfilecontent
|
|
||||||
#define headerfilecontent
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <fcgiapp.h>
|
|
||||||
|
|
||||||
#include "templates.h"
|
|
||||||
#include "request.h"
|
|
||||||
#include "error.h"
|
|
||||||
#include "misc.h"
|
|
||||||
#include "db.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Content
|
|
||||||
{
|
|
||||||
// index to request.get_table
|
|
||||||
// set after calling MakeDirectoryStructure()
|
|
||||||
// index of the last item which is not a directory (or is equal get_table.size())
|
|
||||||
GetTable::size_type get_index;
|
|
||||||
|
|
||||||
|
|
||||||
// temporarily object used for some purposes
|
|
||||||
Item item;
|
|
||||||
|
|
||||||
|
|
||||||
Templates templates;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddItem();
|
|
||||||
void EditItem();
|
|
||||||
void LogUser();
|
|
||||||
|
|
||||||
void MakeDirectoryStructure();
|
|
||||||
Request::Result StandardFunction(std::string & name);
|
|
||||||
void PrepareUrlSubject(Item & item);
|
|
||||||
bool MakeGetCheckDir();
|
|
||||||
|
|
||||||
void MakeEditItem();
|
|
||||||
void MakeShowItemById();
|
|
||||||
void MakeDelItem();
|
|
||||||
void MakeLogout();
|
|
||||||
void MakeStandardFunction();
|
|
||||||
|
|
||||||
|
|
||||||
void AppendCurDir(std::string & dir);
|
|
||||||
|
|
||||||
void MakePost();
|
|
||||||
void MakeGet();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
bool Init();
|
|
||||||
|
|
||||||
void Make();
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfilecookieparser
|
|
||||||
#define headerfilecookieparser
|
|
||||||
|
|
||||||
#include <fcgiapp.h>
|
|
||||||
#include "httpsimpleparser.h"
|
|
||||||
#include "requesttypes.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CookieParser : public HttpSimpleParser
|
|
||||||
{
|
|
||||||
|
|
||||||
const char * cookie_string;
|
|
||||||
CookieTable & cookie_table;
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
|
|
||||||
virtual int GetChar()
|
|
||||||
{
|
|
||||||
if( !cookie_string || *cookie_string == 0 )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return (int)(unsigned char)*(cookie_string++);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
virtual void Parameter(std::string & name, std::string & value)
|
|
||||||
{
|
|
||||||
// Cookie names are case insensitive according to section 3.1 of RFC 2965
|
|
||||||
ToLower(name);
|
|
||||||
|
|
||||||
std::pair<CookieTable::iterator, bool> res = cookie_table.insert( std::make_pair(name, value) );
|
|
||||||
|
|
||||||
log << log2 << "Cookie, name: \"" << name << "\", value: \"" << value << "\"";
|
|
||||||
|
|
||||||
if( res.second == false )
|
|
||||||
log << log2 << " (skipped)";
|
|
||||||
|
|
||||||
log << log2 << logend;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
CookieParser(const char * cookie_string_, CookieTable & cookie_table_) : cookie_string(cookie_string_), cookie_table(cookie_table_)
|
|
||||||
{
|
|
||||||
HttpSimpleParser::separator = ';';
|
|
||||||
HttpSimpleParser::value_can_be_quoted = true;
|
|
||||||
HttpSimpleParser::skip_white_chars = true;
|
|
||||||
HttpSimpleParser::recognize_special_chars = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "data.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Data::Data()
|
|
||||||
{
|
|
||||||
// all these data will be reading from a config file
|
|
||||||
|
|
||||||
log_file = "cmslu.log";
|
|
||||||
fcgi_socket = "/var/cmslu/s1";
|
|
||||||
fcgi_socket_chmod = 0770;
|
|
||||||
fcgi_socket_user = "tomek";
|
|
||||||
fcgi_socket_group = "www";
|
|
||||||
|
|
||||||
log_level = 2;
|
|
||||||
log_stdout = true;
|
|
||||||
|
|
||||||
templates = "../httpd/templates"; // templates dir
|
|
||||||
default_index = "index.html";
|
|
||||||
http_session_id_name = "slimaczek_sid";
|
|
||||||
db_database = "tomek";
|
|
||||||
db_user = "tomek";
|
|
||||||
db_pass = "monitorekasd";
|
|
||||||
|
|
||||||
// !! add a method which will be adding a slash at the end of url-es
|
|
||||||
base_url = "http://s10.slimaczek.pl/"; // with a slash at the end
|
|
||||||
|
|
||||||
one_item_is_showed = true;
|
|
||||||
|
|
||||||
dir.root.default_item = 134;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-88
@@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfiledata
|
|
||||||
#define headerfiledata
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "misc.h"
|
|
||||||
#include "item.h"
|
|
||||||
#include "error.h"
|
|
||||||
#include "dir.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Data
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// log file name
|
|
||||||
std::string log_file;
|
|
||||||
|
|
||||||
// 1 - minimum
|
|
||||||
// 2 - (default)
|
|
||||||
// 3 - maximum - all logs
|
|
||||||
int log_level;
|
|
||||||
|
|
||||||
// logging to stdout too
|
|
||||||
bool log_stdout;
|
|
||||||
|
|
||||||
|
|
||||||
// fast cgi: socket (unix domain)
|
|
||||||
std::string fcgi_socket;
|
|
||||||
|
|
||||||
// fast cgi: socket permissions
|
|
||||||
int fcgi_socket_chmod;
|
|
||||||
|
|
||||||
// fast cgi: owner of the socket
|
|
||||||
std::string fcgi_socket_user;
|
|
||||||
|
|
||||||
// fast cgi: group of the socket
|
|
||||||
std::string fcgi_socket_group;
|
|
||||||
|
|
||||||
std::string templates;
|
|
||||||
std::string default_index;
|
|
||||||
|
|
||||||
std::string db_database;
|
|
||||||
std::string db_user;
|
|
||||||
std::string db_pass;
|
|
||||||
std::string base_url;
|
|
||||||
std::string http_session_id_name;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Dir dir;
|
|
||||||
|
|
||||||
|
|
||||||
// if there is one item in a directory
|
|
||||||
// it will be showed
|
|
||||||
// (instead of showing directory contents)
|
|
||||||
bool one_item_is_showed;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Data();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern Data data;
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
-668
@@ -1,668 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "db.h"
|
|
||||||
|
|
||||||
|
|
||||||
Db::Db()
|
|
||||||
{
|
|
||||||
pg_conn = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Db::~Db()
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Db::Init(const std::string & d, const std::string & u, const std::string & p)
|
|
||||||
{
|
|
||||||
db_database = d;
|
|
||||||
db_user = u;
|
|
||||||
db_pass = p;
|
|
||||||
|
|
||||||
Connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Db::Connect()
|
|
||||||
{
|
|
||||||
std::ostringstream buf;
|
|
||||||
buf << "dbname=" << db_database << " user=" << db_user << " password=" << db_pass;
|
|
||||||
|
|
||||||
pg_conn = PQconnectdb(buf.str().c_str());
|
|
||||||
|
|
||||||
if( !pg_conn )
|
|
||||||
log << log1 << "Db: Fatal error during connecting" << logend;
|
|
||||||
|
|
||||||
if( PQsetClientEncoding(pg_conn, "LATIN2") == -1 )
|
|
||||||
log << log1 << "Db: Can't set the proper client encoding" << logend;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Db::Close()
|
|
||||||
{
|
|
||||||
if( pg_conn )
|
|
||||||
{
|
|
||||||
PQfinish(pg_conn);
|
|
||||||
pg_conn = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Db::AssertConnection()
|
|
||||||
{
|
|
||||||
if( !pg_conn )
|
|
||||||
{
|
|
||||||
log << log1 << "Db: Trying to connect into the database...";
|
|
||||||
Connect();
|
|
||||||
|
|
||||||
if( !pg_conn )
|
|
||||||
// logend from Connect()
|
|
||||||
throw Error(Error::db_fatal_error_during_connecting);
|
|
||||||
|
|
||||||
log << log1 << "ok" << logend;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( PQstatus(pg_conn) != CONNECTION_OK )
|
|
||||||
{
|
|
||||||
log << log2 << "Db: connection into the database is lost, trying to recover..." << logend;
|
|
||||||
PQreset(pg_conn);
|
|
||||||
|
|
||||||
if( PQstatus(pg_conn) != CONNECTION_OK )
|
|
||||||
{
|
|
||||||
log << log2 << "no" << logend;
|
|
||||||
throw Error(Error::db_fatal_error_during_connecting);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log << log2 << "ok" << logend;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string Db::Escape(const std::string & s)
|
|
||||||
{
|
|
||||||
std::string result;
|
|
||||||
|
|
||||||
result.resize(s.length() * 2 + 1);
|
|
||||||
|
|
||||||
size_t len = PQescapeStringConn(pg_conn, const_cast<char*>( result.c_str() ), s.c_str(), s.length(), 0);
|
|
||||||
result.resize(len);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string Db::Escape(const char * s)
|
|
||||||
{
|
|
||||||
std::string result;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
for(len=0 ; s[len] != 0 ; ++len);
|
|
||||||
|
|
||||||
result.resize(len * 2 + 1);
|
|
||||||
|
|
||||||
size_t len_new = PQescapeStringConn(pg_conn, const_cast<char*>( result.c_str() ), s, len, 0);
|
|
||||||
result.resize(len_new);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PGresult * Db::AssertQuery(const std::string & q)
|
|
||||||
{
|
|
||||||
PGresult * r = PQexec(pg_conn, q.c_str());
|
|
||||||
|
|
||||||
if( !r )
|
|
||||||
{
|
|
||||||
log << log1 << "Db: Problem with query: " << PQerrorMessage(pg_conn) << logend;
|
|
||||||
throw Error(Error::db_incorrect_query);
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Db::AssertResultStatus(PGresult * r, ExecStatusType t)
|
|
||||||
{
|
|
||||||
if( PQresultStatus(r) != t )
|
|
||||||
{
|
|
||||||
log << "Db: Incorrect result status: " << PQerrorMessage(pg_conn) << logend;
|
|
||||||
|
|
||||||
throw Error(Error::db_incorrent_result_status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int Db::AssertColumn(PGresult * r, const char * column_name)
|
|
||||||
{
|
|
||||||
int c = PQfnumber(r, column_name);
|
|
||||||
|
|
||||||
if( c == -1 )
|
|
||||||
{
|
|
||||||
log << log1 << "Db: there is no column: " << column_name << logend;
|
|
||||||
|
|
||||||
throw Error(Error::db_no_column);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char * Db::AssertValue(PGresult * r, int row, int col)
|
|
||||||
{
|
|
||||||
const char * res = PQgetvalue(r, row, col);
|
|
||||||
|
|
||||||
if( !res )
|
|
||||||
{
|
|
||||||
log << log1 << "Db: there is no such an item in the result, row:" << row << ", col:" << col << logend;
|
|
||||||
|
|
||||||
throw Error(Error::db_no_item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Db::ClearResult(PGresult * r)
|
|
||||||
{
|
|
||||||
if( r )
|
|
||||||
PQclear(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Db::CheckUser(std::string & login, std::string & password, long & user_id)
|
|
||||||
{
|
|
||||||
PGresult * r = 0;
|
|
||||||
bool user_ok = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AssertConnection();
|
|
||||||
|
|
||||||
std::ostringstream query;
|
|
||||||
query << "select id from core.user where login='" << Escape(login) << "' and password='" << Escape(password) << "';";
|
|
||||||
|
|
||||||
r = AssertQuery( query.str() );
|
|
||||||
|
|
||||||
AssertResultStatus(r, PGRES_TUPLES_OK);
|
|
||||||
|
|
||||||
int rows = PQntuples(r);
|
|
||||||
|
|
||||||
if( rows == 0 )
|
|
||||||
throw Error(Error::db_incorrect_login);
|
|
||||||
|
|
||||||
if( rows > 1 )
|
|
||||||
{
|
|
||||||
log << log1 << "Db: there is more than one user: " << login << " (with the same password)" << logend;
|
|
||||||
throw Error(Error::db_more_than_one_login);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cuser_id = AssertColumn(r, "id");
|
|
||||||
const char * fuser_id = AssertValue(r, 0, cuser_id);
|
|
||||||
user_id = atol( fuser_id );
|
|
||||||
|
|
||||||
user_ok = true;
|
|
||||||
}
|
|
||||||
catch(const Error &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearResult(r);
|
|
||||||
|
|
||||||
|
|
||||||
return user_ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Db::AddItemCreateUrlSubject(Item & item)
|
|
||||||
{
|
|
||||||
bool is_that_url;
|
|
||||||
PGresult * r = 0;
|
|
||||||
int index = 1;
|
|
||||||
const int max_index = 100;
|
|
||||||
char appendix[20];
|
|
||||||
appendix[0] = 0;
|
|
||||||
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
std::ostringstream query;
|
|
||||||
|
|
||||||
// this Escape can be put at the beginning (performance)
|
|
||||||
query << "select id from core.item where url_subject='" << Escape(item.url_subject) << appendix << "' and parent_id='" << item.parent_id << "';";
|
|
||||||
r = AssertQuery(query.str());
|
|
||||||
AssertResultStatus(r, PGRES_TUPLES_OK);
|
|
||||||
|
|
||||||
if( PQntuples(r) != 0 )
|
|
||||||
{
|
|
||||||
sprintf(appendix, "_(%d)", ++index);
|
|
||||||
is_that_url = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item.url_subject += appendix;
|
|
||||||
is_that_url = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearResult(r);
|
|
||||||
r = 0;
|
|
||||||
}
|
|
||||||
while( is_that_url && index <= max_index );
|
|
||||||
}
|
|
||||||
catch(const Error &)
|
|
||||||
{
|
|
||||||
is_that_url = true; // for return false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ClearResult(r);
|
|
||||||
|
|
||||||
|
|
||||||
return !is_that_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// for testing consistency
|
|
||||||
void Db::CheckAllUrlSubjectModifyItem(Item & item)
|
|
||||||
{
|
|
||||||
PGresult * r = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::ostringstream query;
|
|
||||||
query << "update core.item set url_subject=";
|
|
||||||
|
|
||||||
// url_subject
|
|
||||||
if( AddItemCreateUrlSubject(item) )
|
|
||||||
query << '\'' << Escape(item.url_subject) << '\'';
|
|
||||||
else
|
|
||||||
{
|
|
||||||
query << '\'' << item.id << '\'';
|
|
||||||
item.url_subject.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
query << " where id='" << item.id << "';";
|
|
||||||
|
|
||||||
r = AssertQuery(query.str());
|
|
||||||
AssertResultStatus(r, PGRES_COMMAND_OK);
|
|
||||||
}
|
|
||||||
catch(const Error &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearResult(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// for checking consistency
|
|
||||||
void Db::CheckAllUrlSubject()
|
|
||||||
{
|
|
||||||
PGresult * r = 0;
|
|
||||||
Item item;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AssertConnection();
|
|
||||||
std::ostringstream query, query2;
|
|
||||||
query << "select id, subject from core.item where url_subject is null or url_subject=''";
|
|
||||||
|
|
||||||
r = AssertQuery(query.str());
|
|
||||||
AssertResultStatus(r, PGRES_TUPLES_OK);
|
|
||||||
|
|
||||||
int rows = PQntuples(r);
|
|
||||||
int cid = AssertColumn(r, "id");
|
|
||||||
int csubject = AssertColumn(r, "subject");
|
|
||||||
|
|
||||||
for(int i = 0 ; i<rows ; ++i)
|
|
||||||
{
|
|
||||||
item.id = atol( AssertValue(r, i, cid) );
|
|
||||||
item.subject = AssertValue(r, i, csubject);
|
|
||||||
|
|
||||||
CheckAllUrlSubjectModifyItem(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(const Error &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearResult(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
long Db::AssertCurrval(const char * table)
|
|
||||||
{
|
|
||||||
PGresult * r;
|
|
||||||
std::ostringstream query;
|
|
||||||
|
|
||||||
query << "select currval('" << table << "');";
|
|
||||||
|
|
||||||
r = AssertQuery(query.str());
|
|
||||||
AssertResultStatus(r, PGRES_TUPLES_OK);
|
|
||||||
|
|
||||||
if( PQntuples(r) != 1 )
|
|
||||||
{
|
|
||||||
log << log1 << "Db: error (currval) for table: " << table << ", " << PQerrorMessage(pg_conn) << logend;
|
|
||||||
throw Error(Error::db_err_currval);
|
|
||||||
}
|
|
||||||
|
|
||||||
long res = strtol( AssertValue(r, 0, 0), 0, 10 );
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Error Db::AddItem(Item & item)
|
|
||||||
{
|
|
||||||
PGresult * r = 0;
|
|
||||||
Error result = Error::ok;
|
|
||||||
bool url_without_id = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AssertConnection();
|
|
||||||
std::ostringstream query;
|
|
||||||
query << "insert into core.item (subject, content, url_subject, type, parent_id) values (";
|
|
||||||
query << '\'' << Escape(item.subject) << "', ";
|
|
||||||
query << '\'' << Escape(item.content) << "', ";
|
|
||||||
|
|
||||||
// url_subject
|
|
||||||
url_without_id = AddItemCreateUrlSubject(item);
|
|
||||||
|
|
||||||
if( url_without_id )
|
|
||||||
{
|
|
||||||
query << '\'' << Escape(item.url_subject) << "', ";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
query << "currval('core.item_id_seq')" << ", ";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
query << '\'' << static_cast<int>(item.type) << "', ";
|
|
||||||
query << '\'' << item.parent_id << "' ";
|
|
||||||
query << ");";
|
|
||||||
|
|
||||||
r = AssertQuery(query.str());
|
|
||||||
AssertResultStatus(r, PGRES_COMMAND_OK);
|
|
||||||
|
|
||||||
item.id = AssertCurrval("core.item_id_seq");
|
|
||||||
|
|
||||||
if( !url_without_id )
|
|
||||||
ToString(item.url_subject, item.id);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(const Error & e)
|
|
||||||
{
|
|
||||||
result = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearResult(r);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Error Db::EditItem(Item & item, bool with_subject)
|
|
||||||
{
|
|
||||||
PGresult * r = 0;
|
|
||||||
Error result = Error::ok;
|
|
||||||
bool url_without_id = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AssertConnection();
|
|
||||||
std::ostringstream query;
|
|
||||||
query << "update core.item set (";
|
|
||||||
|
|
||||||
if( with_subject )
|
|
||||||
query << "subject, url_subject, ";
|
|
||||||
|
|
||||||
query << "content, type, parent_id) = (";
|
|
||||||
|
|
||||||
if( with_subject )
|
|
||||||
{
|
|
||||||
query << '\'' << Escape(item.subject) << "', ";
|
|
||||||
|
|
||||||
// url_subject
|
|
||||||
url_without_id = AddItemCreateUrlSubject(item);
|
|
||||||
|
|
||||||
if( url_without_id )
|
|
||||||
{
|
|
||||||
query << '\'' << Escape(item.url_subject) << "', ";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
query << '\'' << item.id << "', ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
query << '\'' << Escape(item.content) << "', ";
|
|
||||||
|
|
||||||
query << '\'' << static_cast<int>(item.type) << "', ";
|
|
||||||
query << '\'' << item.parent_id << "' ";
|
|
||||||
query << ") where id='" << item.id << "';";
|
|
||||||
|
|
||||||
r = AssertQuery(query.str());
|
|
||||||
AssertResultStatus(r, PGRES_COMMAND_OK);
|
|
||||||
|
|
||||||
if( with_subject && !url_without_id )
|
|
||||||
ToString(item.url_subject, item.id);
|
|
||||||
}
|
|
||||||
catch(const Error & e)
|
|
||||||
{
|
|
||||||
result = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearResult(r);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PGresult * Db::GetItemsQuery(Item & item_ref)
|
|
||||||
{
|
|
||||||
std::ostringstream query;
|
|
||||||
query << "select * from core.item where type!='0' and parent_id='" << item_ref.parent_id << "'";
|
|
||||||
|
|
||||||
if( item_ref.id != -1 )
|
|
||||||
query << " and id='" << item_ref.id << "'";
|
|
||||||
|
|
||||||
if( !item_ref.url_subject.empty() )
|
|
||||||
query << " and url_subject='" << Escape(item_ref.url_subject) << "'";
|
|
||||||
|
|
||||||
query << ';';
|
|
||||||
|
|
||||||
return AssertQuery(query.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Db::GetItems(std::vector<Item> & item_table, Item & item_ref)
|
|
||||||
{
|
|
||||||
item_table.clear();
|
|
||||||
PGresult * r = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AssertConnection();
|
|
||||||
|
|
||||||
r = GetItemsQuery(item_ref);
|
|
||||||
AssertResultStatus(r, PGRES_TUPLES_OK);
|
|
||||||
|
|
||||||
Item item;
|
|
||||||
int rows = PQntuples(r);
|
|
||||||
|
|
||||||
ItemColumns col;
|
|
||||||
col.SetColumns(r);
|
|
||||||
|
|
||||||
for(int i = 0 ; i<rows ; ++i)
|
|
||||||
{
|
|
||||||
col.SetItem(r, i, item);
|
|
||||||
item_table.push_back(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(const Error &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearResult(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Db::GetItem(std::vector<Item> & item_table, long id)
|
|
||||||
{
|
|
||||||
PGresult * r = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AssertConnection();
|
|
||||||
|
|
||||||
std::ostringstream query;
|
|
||||||
query << "select * from core.item where type='1' and id='" << id << "';";
|
|
||||||
|
|
||||||
r = AssertQuery( query.str() );
|
|
||||||
AssertResultStatus(r, PGRES_TUPLES_OK);
|
|
||||||
|
|
||||||
Item item;
|
|
||||||
int rows = PQntuples(r);
|
|
||||||
|
|
||||||
if( rows > 1 )
|
|
||||||
log << log1 << "Db: we have more than one item with id: " << id << logend;
|
|
||||||
|
|
||||||
ItemColumns col;
|
|
||||||
col.SetColumns(r);
|
|
||||||
|
|
||||||
for(int i = 0 ; i<rows ; ++i)
|
|
||||||
{
|
|
||||||
col.SetItem(r, i, item);
|
|
||||||
item_table.push_back(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(const Error &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearResult(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Db::DelItem(long id)
|
|
||||||
{
|
|
||||||
long rows = 0;
|
|
||||||
PGresult * r = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AssertConnection();
|
|
||||||
|
|
||||||
std::ostringstream query;
|
|
||||||
query << "delete from core.item where type='1' and id='" << id << "';";
|
|
||||||
|
|
||||||
r = AssertQuery( query.str() );
|
|
||||||
AssertResultStatus(r, PGRES_COMMAND_OK);
|
|
||||||
|
|
||||||
const char * crows = PQcmdTuples(r);
|
|
||||||
if( crows )
|
|
||||||
{
|
|
||||||
rows = atol(crows);
|
|
||||||
|
|
||||||
if( rows > 1 )
|
|
||||||
log << log1 << "Db: more than one item were deleted" << logend;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(const Error &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearResult(r);
|
|
||||||
|
|
||||||
return rows != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Db::GetDirs(DirContainer & dir_table)
|
|
||||||
{
|
|
||||||
PGresult * r = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AssertConnection();
|
|
||||||
|
|
||||||
std::ostringstream query;
|
|
||||||
query << "select * from core.item where type='0';";
|
|
||||||
|
|
||||||
r = AssertQuery( query.str() );
|
|
||||||
AssertResultStatus(r, PGRES_TUPLES_OK);
|
|
||||||
|
|
||||||
Item item;
|
|
||||||
int rows = PQntuples(r);
|
|
||||||
|
|
||||||
ItemColumns col;
|
|
||||||
col.SetColumns(r);
|
|
||||||
|
|
||||||
for(int i = 0 ; i<rows ; ++i)
|
|
||||||
{
|
|
||||||
col.SetItem(r, i, item);
|
|
||||||
dir_table.PushBack( item );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(const Error &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearResult(r);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfilecoredb
|
|
||||||
#define headerfilecoredb
|
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <sstream>
|
|
||||||
#include <libpq-fe.h>
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
|
|
||||||
#include "log.h"
|
|
||||||
#include "item.h"
|
|
||||||
#include "misc.h"
|
|
||||||
#include "error.h"
|
|
||||||
#include "dircontainer.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Db
|
|
||||||
{
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
PGconn * pg_conn;
|
|
||||||
|
|
||||||
std::string db_database, db_user, db_pass;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Db();
|
|
||||||
~Db();
|
|
||||||
|
|
||||||
void Init(const std::string & database, const std::string & user, const std::string & pass);
|
|
||||||
void Connect();
|
|
||||||
|
|
||||||
void Close();
|
|
||||||
void AssertConnection();
|
|
||||||
std::string Escape(const std::string & s);
|
|
||||||
std::string Escape(const char * s);
|
|
||||||
|
|
||||||
PGresult * AssertQuery(const std::string & q);
|
|
||||||
void AssertResultStatus(PGresult * r, ExecStatusType t);
|
|
||||||
static int AssertColumn(PGresult * r, const char * column_name);
|
|
||||||
static const char * AssertValue(PGresult * r, int row, int col);
|
|
||||||
|
|
||||||
void ClearResult(PGresult * r);
|
|
||||||
|
|
||||||
bool CheckUser(std::string & login, std::string & password, long & user_id);
|
|
||||||
|
|
||||||
long AssertCurrval(const char * table);
|
|
||||||
|
|
||||||
|
|
||||||
bool AddItemCreateUrlSubject(Item & item);
|
|
||||||
Error AddItem(Item & item);
|
|
||||||
Error EditItem(Item & item, bool with_subject = true);
|
|
||||||
|
|
||||||
void CheckAllUrlSubjectModifyItem(Item & item);
|
|
||||||
void CheckAllUrlSubject();
|
|
||||||
|
|
||||||
PGresult * GetItemsQuery(Item & item_ref);
|
|
||||||
void GetItems(std::vector<Item> & item_table, Item & item_ref);
|
|
||||||
void GetItem(std::vector<Item> & item_table, long id);
|
|
||||||
|
|
||||||
bool DelItem(long id);
|
|
||||||
|
|
||||||
void GetDirs(DirContainer & dir_table);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct ItemColumns
|
|
||||||
{
|
|
||||||
int id, subject, content, url_subject, type, parent_id, default_item;
|
|
||||||
|
|
||||||
void SetColumns(PGresult * r)
|
|
||||||
{
|
|
||||||
id = Db::AssertColumn(r, "id");
|
|
||||||
subject = Db::AssertColumn(r, "subject");
|
|
||||||
content = Db::AssertColumn(r, "content");
|
|
||||||
url_subject = Db::AssertColumn(r, "url_subject");
|
|
||||||
type = Db::AssertColumn(r, "type");
|
|
||||||
parent_id = Db::AssertColumn(r, "parent_id");
|
|
||||||
default_item = Db::AssertColumn(r, "default_item");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SetItem(PGresult * r, long row, Item & item)
|
|
||||||
{
|
|
||||||
item.id = atol( Db::AssertValue(r, row, id) );
|
|
||||||
item.subject = Db::AssertValue(r, row, subject);
|
|
||||||
item.content = Db::AssertValue(r, row, content);
|
|
||||||
item.url_subject = Db::AssertValue(r, row, url_subject);
|
|
||||||
item.type = static_cast<Item::Type>( atoi( Db::AssertValue(r, row, type) ) );
|
|
||||||
item.parent_id = atol( Db::AssertValue(r, row, parent_id) );
|
|
||||||
item.default_item = atol( Db::AssertValue(r, row, default_item) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}; // class Db
|
|
||||||
|
|
||||||
|
|
||||||
extern Db db;
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
-220
@@ -1,220 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "dir.h"
|
|
||||||
|
|
||||||
|
|
||||||
void Dir::Clear()
|
|
||||||
{
|
|
||||||
dir_table.Clear();
|
|
||||||
|
|
||||||
// !! temporarily not clearing
|
|
||||||
//root.Clear();
|
|
||||||
root.id = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Dir::ReadDirs()
|
|
||||||
{
|
|
||||||
Clear();
|
|
||||||
|
|
||||||
db.GetDirs(dir_table);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Dir::GetDir(const std::string & name, long parent, Item ** item)
|
|
||||||
{
|
|
||||||
DirContainer::ParentIterator i = dir_table.FindFirstParent(parent);
|
|
||||||
|
|
||||||
for( ; i!=dir_table.ParentEnd() ; i = dir_table.NextParent(i) )
|
|
||||||
if( i->second->url_subject == name )
|
|
||||||
{
|
|
||||||
*item = &(*i->second);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Dir::ExtractName(const char * & s, std::string & name)
|
|
||||||
{
|
|
||||||
name.clear();
|
|
||||||
|
|
||||||
// skipping first slashes (can be more than one)
|
|
||||||
for( ; *s == '/' ; ++s);
|
|
||||||
|
|
||||||
for( ; *s != 0 && *s != '/' ; ++s)
|
|
||||||
name += *s;
|
|
||||||
|
|
||||||
return !name.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Dir::GetDir(const std::string & path, Item ** item)
|
|
||||||
{
|
|
||||||
long parent = -1;
|
|
||||||
std::string name;
|
|
||||||
const char * s = path.c_str();
|
|
||||||
Item * pitem = &root;
|
|
||||||
|
|
||||||
while( ExtractName(s, name) )
|
|
||||||
{
|
|
||||||
if( !GetDir(name, parent, &pitem) )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
*item = pitem;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Dir::GetDirId(const std::string & path, long * id)
|
|
||||||
{
|
|
||||||
Item * pitem;
|
|
||||||
|
|
||||||
if( !GetDir(path, &pitem) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*id = pitem->id;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Dir::GetDirId(const std::string & name, long parent, long * id)
|
|
||||||
{
|
|
||||||
Item * pitem;
|
|
||||||
|
|
||||||
if( !GetDir(name, parent, &pitem) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*id = pitem->id;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Dir::IsDir(long id)
|
|
||||||
{
|
|
||||||
if( id == -1 )
|
|
||||||
// root directory
|
|
||||||
return true;
|
|
||||||
|
|
||||||
DirContainer::Iterator i = dir_table.FindId(id);
|
|
||||||
|
|
||||||
if( i == dir_table.End() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Dir::GetDirChilds(long parent, std::vector<Item> & childs_table)
|
|
||||||
{
|
|
||||||
if( !IsDir(parent) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
DirContainer::ParentIterator i = dir_table.FindFirstParent(parent);
|
|
||||||
|
|
||||||
for( ; i != dir_table.ParentEnd() ; i = dir_table.NextParent(i) )
|
|
||||||
childs_table.push_back( *i->second );
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// dodatkowo moze metoda AppendPath dodajaca sciezke do biezacego stringa?
|
|
||||||
// albo tutaj stringa nie czyscic?
|
|
||||||
// O(m * log n) (m- how many parts are in 'id')
|
|
||||||
bool Dir::MakePath(long id, std::string & path)
|
|
||||||
{
|
|
||||||
DirContainer::Iterator i;
|
|
||||||
|
|
||||||
path.clear();
|
|
||||||
|
|
||||||
while( true )
|
|
||||||
{
|
|
||||||
if( id == -1 )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
i = dir_table.FindId(id);
|
|
||||||
|
|
||||||
if( i == dir_table.End() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
id = i->parent_id;
|
|
||||||
path.insert(path.begin(), '/');
|
|
||||||
path.insert(0, i->url_subject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// with exceptions
|
|
||||||
|
|
||||||
Item * Dir::GetDir(const std::string & path)
|
|
||||||
{
|
|
||||||
Item * pitem;
|
|
||||||
|
|
||||||
if( !GetDir(path, &pitem) )
|
|
||||||
throw Error(Error::incorrect_dir);
|
|
||||||
|
|
||||||
return pitem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Item * Dir::GetDir(const std::string & name, long parent)
|
|
||||||
{
|
|
||||||
Item * pitem;
|
|
||||||
|
|
||||||
if( !GetDir(name, parent, &pitem) )
|
|
||||||
throw Error(Error::incorrect_dir);
|
|
||||||
|
|
||||||
return pitem;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
long Dir::GetDirId(const std::string & path)
|
|
||||||
{
|
|
||||||
long id;
|
|
||||||
|
|
||||||
if( !GetDirId(path, &id) )
|
|
||||||
throw Error(Error::incorrect_dir);
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
long Dir::GetDirId(const std::string & name, long parent)
|
|
||||||
{
|
|
||||||
long id;
|
|
||||||
|
|
||||||
if( !GetDirId(name, parent, &id) )
|
|
||||||
throw Error(Error::incorrect_dir);
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-80
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfiledir
|
|
||||||
#define headerfiledir
|
|
||||||
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include "item.h"
|
|
||||||
#include "error.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "db.h"
|
|
||||||
#include "dircontainer.h"
|
|
||||||
|
|
||||||
|
|
||||||
class Dir
|
|
||||||
{
|
|
||||||
|
|
||||||
private:
|
|
||||||
public: // !! temporarily
|
|
||||||
|
|
||||||
|
|
||||||
// id = -1;
|
|
||||||
Item root;
|
|
||||||
|
|
||||||
|
|
||||||
DirContainer dir_table;
|
|
||||||
|
|
||||||
|
|
||||||
// parent (or -1), item
|
|
||||||
//typedef std::multimap<long, Item> DirTable;
|
|
||||||
//DirTable dir_table;
|
|
||||||
|
|
||||||
|
|
||||||
bool ExtractName(const char * & s, std::string & name);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void Clear();
|
|
||||||
void ReadDirs();
|
|
||||||
|
|
||||||
// without any exceptions
|
|
||||||
// these methods return false in a case the path or name (with a specific parent) are invalid
|
|
||||||
// we do not support '..' in a path (for security reason)
|
|
||||||
|
|
||||||
bool IsDir(long id);
|
|
||||||
|
|
||||||
bool GetDir(const std::string & path, Item ** item);
|
|
||||||
bool GetDir(const std::string & name, long parent, Item ** item);
|
|
||||||
|
|
||||||
bool GetDirId(const std::string & path, long * id);
|
|
||||||
bool GetDirId(const std::string & name, long parent, long * id);
|
|
||||||
|
|
||||||
bool GetDirChilds(long parent, std::vector<Item> & childs_table); // only returns dir-children
|
|
||||||
|
|
||||||
bool MakePath(long id, std::string & path);
|
|
||||||
|
|
||||||
|
|
||||||
// with an Error exception
|
|
||||||
// if the path or name are invalid these methods throw an exception
|
|
||||||
Item * GetDir(const std::string & path);
|
|
||||||
Item * GetDir(const std::string & name, long parent);
|
|
||||||
long GetDirId(const std::string & path);
|
|
||||||
long GetDirId(const std::string & name, long parent);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "dircontainer.h"
|
|
||||||
|
|
||||||
// !! tutaj ostatecznie ustawic wartosc np okolo 100
|
|
||||||
// chwilowo do testow ustawione 2
|
|
||||||
DirContainer::DirContainer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DirContainer::Iterator DirContainer::Begin()
|
|
||||||
{
|
|
||||||
return table.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DirContainer::Iterator DirContainer::End()
|
|
||||||
{
|
|
||||||
return table.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DirContainer::SizeType DirContainer::Size()
|
|
||||||
{
|
|
||||||
return table.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DirContainer::Empty()
|
|
||||||
{
|
|
||||||
return table.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DirContainer::PushBack(const Item & item)
|
|
||||||
{
|
|
||||||
bool rebuild_indexes = false;
|
|
||||||
|
|
||||||
if( table.size() == table.capacity() )
|
|
||||||
rebuild_indexes = true;
|
|
||||||
|
|
||||||
table.push_back(item);
|
|
||||||
log << log2 << "DirCont: added item, id: " << item.id << ", parent_id: " << item.parent_id << logend;
|
|
||||||
|
|
||||||
if( rebuild_indexes )
|
|
||||||
RebuildIndexes();
|
|
||||||
else
|
|
||||||
AddIndexes( --table.end() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DirContainer::Clear()
|
|
||||||
{
|
|
||||||
table.clear();
|
|
||||||
table_id.clear();
|
|
||||||
table_parent.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DirContainer::Iterator DirContainer::FindId(long id)
|
|
||||||
{
|
|
||||||
TableId::iterator i = table_id.find(id);
|
|
||||||
|
|
||||||
if( i == table_id.end() )
|
|
||||||
return table.end();
|
|
||||||
|
|
||||||
return i->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DirContainer::AddIndexes(Iterator item)
|
|
||||||
{
|
|
||||||
table_id.insert( std::make_pair(item->id, item) );
|
|
||||||
table_parent.insert( std::make_pair(item->parent_id, item) );
|
|
||||||
|
|
||||||
log << log2 << "DirCont: added indexes to item, id: " << item->id << ", parent_id: " << item->parent_id << logend;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DirContainer::RebuildIndexes()
|
|
||||||
{
|
|
||||||
Iterator i;
|
|
||||||
|
|
||||||
log << log2 << "DirCont: rebuilding indexes" << logend;
|
|
||||||
|
|
||||||
table_id.clear();
|
|
||||||
table_parent.clear();
|
|
||||||
|
|
||||||
for(i=table.begin() ; i!=table.end() ; ++i)
|
|
||||||
AddIndexes( i );
|
|
||||||
|
|
||||||
log << log2 << "DirCont: indexes rebuilt, table.size: " << table.size() << ", table_id.size: " << table_id.size() << ", table_parent.size: " << table_parent.size() << logend;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DirContainer::ParentIterator DirContainer::ParentBegin()
|
|
||||||
{
|
|
||||||
return table_parent.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DirContainer::ParentIterator DirContainer::ParentEnd()
|
|
||||||
{
|
|
||||||
return table_parent.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DirContainer::ParentSizeType DirContainer::ParentSize()
|
|
||||||
{
|
|
||||||
return table_parent.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool DirContainer::ParentEmpty()
|
|
||||||
{
|
|
||||||
return table_parent.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DirContainer::ParentIterator DirContainer::FindFirstParent(long parent)
|
|
||||||
{
|
|
||||||
ParentIterator i = table_parent.lower_bound(parent);
|
|
||||||
|
|
||||||
if( i == table_parent.end() || i->first != parent )
|
|
||||||
return table_parent.end();
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DirContainer::ParentIterator DirContainer::NextParent(ParentIterator i)
|
|
||||||
{
|
|
||||||
if( i == table_parent.end() )
|
|
||||||
return table_parent.end();
|
|
||||||
|
|
||||||
long parent = i->first;
|
|
||||||
++i;
|
|
||||||
|
|
||||||
if( i == table_parent.end() || i->first != parent )
|
|
||||||
return table_parent.end();
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfiledircontainer
|
|
||||||
#define headerfiledircontainer
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include "item.h"
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
|
|
||||||
class DirContainer
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef std::vector<Item> Table;
|
|
||||||
typedef Table::iterator Iterator;
|
|
||||||
typedef Table::size_type SizeType;
|
|
||||||
|
|
||||||
typedef std::map<long, Iterator> TableId;
|
|
||||||
typedef std::multimap<long, Iterator> TableParent;
|
|
||||||
typedef TableParent::iterator ParentIterator;
|
|
||||||
typedef TableParent::size_type ParentSizeType;
|
|
||||||
|
|
||||||
|
|
||||||
DirContainer();
|
|
||||||
|
|
||||||
Iterator Begin();
|
|
||||||
Iterator End();
|
|
||||||
SizeType Size();
|
|
||||||
bool Empty();
|
|
||||||
void PushBack(const Item & item);
|
|
||||||
void Clear();
|
|
||||||
|
|
||||||
Iterator FindId(long id);
|
|
||||||
|
|
||||||
ParentIterator ParentBegin();
|
|
||||||
ParentIterator ParentEnd();
|
|
||||||
ParentSizeType ParentSize();
|
|
||||||
bool ParentEmpty();
|
|
||||||
ParentIterator FindFirstParent(long parent);
|
|
||||||
ParentIterator NextParent(ParentIterator pi);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void AddIndexes(Iterator item);
|
|
||||||
void RebuildIndexes();
|
|
||||||
|
|
||||||
// main table with dirs
|
|
||||||
Table table;
|
|
||||||
|
|
||||||
// indexes
|
|
||||||
TableId table_id;
|
|
||||||
TableParent table_parent;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "done.h"
|
|
||||||
|
|
||||||
|
|
||||||
Done::Done()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Done::Done(Code c) : code(c)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Done & Done::operator=(Code c)
|
|
||||||
{
|
|
||||||
code = c;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Done::operator==(Code c) const
|
|
||||||
{
|
|
||||||
return code == c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Done::operator!=(Code c) const
|
|
||||||
{
|
|
||||||
return code != c;
|
|
||||||
}
|
|
||||||
|
|
||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfiledone
|
|
||||||
#define headerfiledone
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// what have been done
|
|
||||||
class Done
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum Code
|
|
||||||
{
|
|
||||||
none,
|
|
||||||
added_item,
|
|
||||||
edited_item,
|
|
||||||
deleted_item,
|
|
||||||
loggedout
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Done();
|
|
||||||
Done(Code c);
|
|
||||||
Done & operator=(Code c);
|
|
||||||
bool operator==(Code c) const;
|
|
||||||
bool operator!=(Code c) const;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Code code;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "error.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Error::Error()
|
|
||||||
{
|
|
||||||
code = unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Error::Error(Code c) : code(c)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Error::Error(int i)
|
|
||||||
{
|
|
||||||
code = static_cast<Code>(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Error::operator int() const
|
|
||||||
{
|
|
||||||
return static_cast<int>(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Error & Error::operator=(Code c)
|
|
||||||
{
|
|
||||||
code = c;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Error::operator==(Code c) const
|
|
||||||
{
|
|
||||||
return code == c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Error::operator!=(Code c) const
|
|
||||||
{
|
|
||||||
return code != c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & out, const Error & e)
|
|
||||||
{
|
|
||||||
out << static_cast<int>(e.code);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Log & operator<<(Log & out, const Error & e)
|
|
||||||
{
|
|
||||||
out << static_cast<int>(e.code);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfileerror
|
|
||||||
#define headerfileerror
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Error
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum Code
|
|
||||||
{
|
|
||||||
ok = 0,
|
|
||||||
incorrect_path,
|
|
||||||
db_fatal_error_during_connecting,
|
|
||||||
db_incorrect_query,
|
|
||||||
db_incorrent_result_status,
|
|
||||||
db_no_column,
|
|
||||||
db_no_item,
|
|
||||||
db_incorrect_login,
|
|
||||||
db_more_than_one_login,
|
|
||||||
db_err_currval,
|
|
||||||
|
|
||||||
incorrect_dir,
|
|
||||||
|
|
||||||
unknown = 1000
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Error();
|
|
||||||
Error(Code c);
|
|
||||||
Error(int i);
|
|
||||||
Error & operator=(Code c);
|
|
||||||
|
|
||||||
operator int() const;
|
|
||||||
|
|
||||||
bool operator==(Code c) const;
|
|
||||||
bool operator!=(Code c) const;
|
|
||||||
|
|
||||||
friend std::ostream & operator<<(std::ostream & out, const Error & e);
|
|
||||||
friend Log & operator<<(Log & out, const Error & e);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Code code;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & out, const Error & e);
|
|
||||||
Log & operator<<(Log & out, const Error & e);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfilegetparser
|
|
||||||
#define headerfilegetparser
|
|
||||||
|
|
||||||
#include "httpsimpleparser.h"
|
|
||||||
#include "requesttypes.h"
|
|
||||||
|
|
||||||
|
|
||||||
class GetParser : public HttpSimpleParser
|
|
||||||
{
|
|
||||||
|
|
||||||
const char * get_string;
|
|
||||||
GetTable & get_table;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual int GetChar()
|
|
||||||
{
|
|
||||||
if( !get_string || *get_string == 0 )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return (int)(unsigned char)*(get_string++);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
virtual void Parameter(std::string &, std::string & value)
|
|
||||||
{
|
|
||||||
get_table.push_back(value);
|
|
||||||
|
|
||||||
log << log2 << "Get, value: \"" << value << "\"" << logend;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
GetParser(const char * get_string_, GetTable & get_table_) : get_string(get_string_), get_table(get_table_)
|
|
||||||
{
|
|
||||||
HttpSimpleParser::separator = '/';
|
|
||||||
HttpSimpleParser::read_name = false;
|
|
||||||
|
|
||||||
if( get_string && *get_string == separator ) // one '/' at the beginning
|
|
||||||
++get_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,231 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "httpsimpleparser.h"
|
|
||||||
|
|
||||||
|
|
||||||
void HttpSimpleParser::ToLower(std::string & s)
|
|
||||||
{
|
|
||||||
std::string::iterator i;
|
|
||||||
|
|
||||||
for(i=s.begin() ; i!= s.end() ; ++i)
|
|
||||||
{
|
|
||||||
if( *i>='A' && *i<='Z' )
|
|
||||||
*i = *i - 'A' + 'a';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool HttpSimpleParser::IsWhite(int c)
|
|
||||||
{
|
|
||||||
if( c==' ' || c=='\t' )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void HttpSimpleParser::SkipWhiteChars()
|
|
||||||
{
|
|
||||||
while( IsWhite(last_c) )
|
|
||||||
last_c = GetChar();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void HttpSimpleParser::TrimWhiteChars(std::string & s)
|
|
||||||
{
|
|
||||||
if( s.empty() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string::size_type i;
|
|
||||||
|
|
||||||
for(i = 0 ; i<s.size() && IsWhite(s[i]) ; ++i);
|
|
||||||
|
|
||||||
if( i == s.size() )
|
|
||||||
{
|
|
||||||
// all characters are white
|
|
||||||
s.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( i > 0 )
|
|
||||||
// there are some white characters at the beginning
|
|
||||||
s.erase(0, i);
|
|
||||||
|
|
||||||
|
|
||||||
// s is not empty now (i was not equal s.size())
|
|
||||||
// and we have some non white characters
|
|
||||||
// we stops at the last non white character
|
|
||||||
for(i = s.size()-1 ; i>0 && IsWhite(s[i]) ; --i);
|
|
||||||
|
|
||||||
if( i != s.size()-1 )
|
|
||||||
// there are some white characters at the end
|
|
||||||
// we're starting from i+1 even when i==0 (there are some non white characters)
|
|
||||||
s.erase(i+1, s.size() - i - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int HttpSimpleParser::ParseHalfHex(int c)
|
|
||||||
{
|
|
||||||
if( c>='a' && c<='z' )
|
|
||||||
c += 'A' - 'a'; // to upper case
|
|
||||||
|
|
||||||
|
|
||||||
if( c >= 'A' )
|
|
||||||
c = c - 'A' + 10;
|
|
||||||
else
|
|
||||||
c = c - '0';
|
|
||||||
|
|
||||||
c &= 0xf;
|
|
||||||
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void HttpSimpleParser::CheckSpecialChar()
|
|
||||||
{
|
|
||||||
if( last_c == '%' )
|
|
||||||
{
|
|
||||||
int c1 = GetChar();
|
|
||||||
int c2 = GetChar();
|
|
||||||
|
|
||||||
if( c1==-1 || c2==-1 )
|
|
||||||
last_c = -1;
|
|
||||||
|
|
||||||
c1 = ParseHalfHex(c1);
|
|
||||||
c2 = ParseHalfHex(c2);
|
|
||||||
|
|
||||||
last_c = (c1 << 4) + c2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( last_c == '+' )
|
|
||||||
{
|
|
||||||
last_c = ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void HttpSimpleParser::ReadName()
|
|
||||||
{
|
|
||||||
// we're checking 'separator' and '=' because the string is allowed not having '=' (the value is optional)
|
|
||||||
|
|
||||||
for( ; last_c!=-1 && last_c!=separator && last_c!='=' ; last_c = GetChar() )
|
|
||||||
{
|
|
||||||
if( recognize_special_chars )
|
|
||||||
CheckSpecialChar();
|
|
||||||
|
|
||||||
if( last_c != -1 )
|
|
||||||
last_name += last_c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( last_c == '=' )
|
|
||||||
last_c = GetChar();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void HttpSimpleParser::ReadQuotedValue()
|
|
||||||
{
|
|
||||||
// skipping '"'
|
|
||||||
last_c = GetChar();
|
|
||||||
|
|
||||||
|
|
||||||
for( ; last_c!=-1 && last_c!='"' ; last_c = GetChar() )
|
|
||||||
{
|
|
||||||
if( recognize_special_chars )
|
|
||||||
CheckSpecialChar();
|
|
||||||
|
|
||||||
if( last_c != -1 )
|
|
||||||
last_value += last_c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( last_c == '"' )
|
|
||||||
last_c = GetChar();
|
|
||||||
|
|
||||||
// looking for a separator (skipping)
|
|
||||||
for( ; last_c!=-1 && last_c!=separator ; last_c = GetChar() );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void HttpSimpleParser::ReadValue()
|
|
||||||
{
|
|
||||||
if( skip_white_chars )
|
|
||||||
SkipWhiteChars();
|
|
||||||
|
|
||||||
if( value_can_be_quoted && last_c == '"' )
|
|
||||||
{
|
|
||||||
ReadQuotedValue();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for( ; last_c!=-1 && last_c!=separator ; last_c = GetChar() )
|
|
||||||
{
|
|
||||||
if( recognize_special_chars )
|
|
||||||
CheckSpecialChar();
|
|
||||||
|
|
||||||
if( last_c != -1 )
|
|
||||||
last_value += last_c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( last_c == separator )
|
|
||||||
last_c = GetChar();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void HttpSimpleParser::Parse()
|
|
||||||
{
|
|
||||||
for( last_c = GetChar() ; last_c != -1 ; )
|
|
||||||
{
|
|
||||||
last_name.clear();
|
|
||||||
last_value.clear();
|
|
||||||
|
|
||||||
if( read_name )
|
|
||||||
ReadName();
|
|
||||||
|
|
||||||
ReadValue();
|
|
||||||
|
|
||||||
if( skip_white_chars )
|
|
||||||
{
|
|
||||||
TrimWhiteChars(last_name);
|
|
||||||
TrimWhiteChars(last_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Parameter(last_name, last_value); // user definied function
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfilehttpsimpleparser
|
|
||||||
#define headerfilehttpsimpleparser
|
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class HttpSimpleParser
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
bool read_name;
|
|
||||||
bool value_can_be_quoted;
|
|
||||||
bool skip_white_chars;
|
|
||||||
bool recognize_special_chars;
|
|
||||||
|
|
||||||
int ParseHalfHex(int c);
|
|
||||||
void ReadName();
|
|
||||||
void ReadQuotedValue();
|
|
||||||
void ReadValue();
|
|
||||||
|
|
||||||
std::string last_name;
|
|
||||||
std::string last_value;
|
|
||||||
|
|
||||||
int last_c;
|
|
||||||
int separator;
|
|
||||||
|
|
||||||
// '-1' means end (eof)
|
|
||||||
virtual int GetChar() = 0;
|
|
||||||
virtual void Parameter(std::string & last_name, std::string & last_value) = 0;
|
|
||||||
|
|
||||||
void ToLower(std::string & s);
|
|
||||||
bool IsWhite(int c);
|
|
||||||
|
|
||||||
void SkipWhiteChars();
|
|
||||||
void TrimWhiteChars(std::string & s);
|
|
||||||
void CheckSpecialChar();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
HttpSimpleParser()
|
|
||||||
{
|
|
||||||
separator = '&';
|
|
||||||
read_name = true;
|
|
||||||
value_can_be_quoted = false;
|
|
||||||
skip_white_chars = false;
|
|
||||||
recognize_special_chars = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Parse();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
-73
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfileitem
|
|
||||||
#define headerfileitem
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Item
|
|
||||||
{
|
|
||||||
long id;
|
|
||||||
|
|
||||||
std::string subject;
|
|
||||||
std::string content;
|
|
||||||
std::string url_subject;
|
|
||||||
|
|
||||||
enum Type
|
|
||||||
{
|
|
||||||
dir = 0,
|
|
||||||
file = 1,
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
none = 1000
|
|
||||||
};
|
|
||||||
|
|
||||||
Type type;
|
|
||||||
|
|
||||||
//item_type;
|
|
||||||
|
|
||||||
long parent_id;
|
|
||||||
long default_item;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Item()
|
|
||||||
{
|
|
||||||
Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Clear()
|
|
||||||
{
|
|
||||||
id = -1;
|
|
||||||
subject.clear();
|
|
||||||
content.clear();
|
|
||||||
url_subject.clear();
|
|
||||||
|
|
||||||
type = none;
|
|
||||||
parent_id = -1;
|
|
||||||
default_item = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
-177
@@ -1,177 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Log::Log()
|
|
||||||
{
|
|
||||||
log_level = 1;
|
|
||||||
current_level = 2;
|
|
||||||
log_file = "cmslu.log";
|
|
||||||
log_stdout = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Log::Init(int log_l, const std::string & log_f, bool log_std)
|
|
||||||
{
|
|
||||||
log_level = log_l;
|
|
||||||
log_file = log_f;
|
|
||||||
log_stdout = log_std;
|
|
||||||
}
|
|
||||||
|
|
||||||
// zrobic templeta z tych metod
|
|
||||||
// i dla const char * zrobic specjalizacje
|
|
||||||
|
|
||||||
Log & Log::operator<<(const char * s)
|
|
||||||
{
|
|
||||||
if( !s )
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
buffer << s;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Log & Log::operator<<(const std::string & s)
|
|
||||||
{
|
|
||||||
buffer << s;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Log & Log::operator<<(int s)
|
|
||||||
{
|
|
||||||
buffer << s;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Log & Log::operator<<(long s)
|
|
||||||
{
|
|
||||||
buffer << s;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Log & Log::operator<<(void * s)
|
|
||||||
{
|
|
||||||
buffer << s;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
Log & Log::operator<<(char s)
|
|
||||||
{
|
|
||||||
buffer << s;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Log & Log::operator<<(size_t s)
|
|
||||||
{
|
|
||||||
buffer << s;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Log & Log::operator<<(Manipulators m)
|
|
||||||
{
|
|
||||||
switch(m)
|
|
||||||
{
|
|
||||||
case logend:
|
|
||||||
SaveLog();
|
|
||||||
buffer.str( "" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case log1:
|
|
||||||
current_level = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case log2:
|
|
||||||
current_level = 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case log3:
|
|
||||||
current_level = 3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Log::SaveLog()
|
|
||||||
{
|
|
||||||
int attempt = 2;
|
|
||||||
|
|
||||||
if( current_level > log_level )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( log_stdout )
|
|
||||||
std::cout << buffer.str() << std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
std::ofstream file;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
file.open( log_file.c_str(), std::ios_base::out | std::ios_base::app );
|
|
||||||
|
|
||||||
// if( !file )
|
|
||||||
// sleep(1);
|
|
||||||
}
|
|
||||||
while( --attempt > 0 && !file );
|
|
||||||
|
|
||||||
if( !file )
|
|
||||||
return;
|
|
||||||
|
|
||||||
file << buffer.str() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-61
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfilelog
|
|
||||||
#define headerfilelog
|
|
||||||
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
enum Manipulators { logend, log1, log2, log3 };
|
|
||||||
|
|
||||||
|
|
||||||
class Log
|
|
||||||
{
|
|
||||||
std::ostringstream buffer;
|
|
||||||
int log_level, current_level;
|
|
||||||
std::string log_file;
|
|
||||||
bool log_stdout;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Log();
|
|
||||||
|
|
||||||
void Init(int log_l, const std::string & log_f, bool log_std);
|
|
||||||
|
|
||||||
|
|
||||||
Log & operator<<(const char * s);
|
|
||||||
Log & operator<<(const std::string & s);
|
|
||||||
Log & operator<<(int s);
|
|
||||||
Log & operator<<(long s);
|
|
||||||
//Log & operator<<(void * s); // ??
|
|
||||||
Log & operator<<(char s);
|
|
||||||
Log & operator<<(size_t s);
|
|
||||||
Log & operator<<(Manipulators m);
|
|
||||||
|
|
||||||
void SaveLog();
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern Log log;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <ctime>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include "requestcontroller.h"
|
|
||||||
#include "data.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "request.h"
|
|
||||||
#include "db.h"
|
|
||||||
|
|
||||||
|
|
||||||
// singletons
|
|
||||||
// first 'data' then 'log' then 'request'
|
|
||||||
Data data;
|
|
||||||
Log log;
|
|
||||||
Request request;
|
|
||||||
Db db;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void signal_term(int)
|
|
||||||
{
|
|
||||||
log << log1 << "system aborted" << logend;
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
std::srand(std::time(0));
|
|
||||||
|
|
||||||
|
|
||||||
log.Init(data.log_level, data.log_file, data.log_stdout);
|
|
||||||
|
|
||||||
|
|
||||||
RequestController req_controller;
|
|
||||||
|
|
||||||
//data.read_from_file();
|
|
||||||
|
|
||||||
|
|
||||||
db.Init(data.db_database, data.db_user, data.db_pass);
|
|
||||||
|
|
||||||
if( !req_controller.Init() )
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
log << log1 << "system started" << logend;
|
|
||||||
|
|
||||||
signal(SIGTERM, signal_term);
|
|
||||||
|
|
||||||
|
|
||||||
log << log1 << "checking for table consistency...";
|
|
||||||
db.CheckAllUrlSubject();
|
|
||||||
log << log1 << "done" << logend;
|
|
||||||
|
|
||||||
|
|
||||||
req_controller.Loop();
|
|
||||||
|
|
||||||
log << log1 << "system stopped" << logend;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
-138
@@ -1,138 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "misc.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ToString(std::string & s, int value)
|
|
||||||
{
|
|
||||||
static char buffer[50];
|
|
||||||
|
|
||||||
sprintf(buffer, "%d", value);
|
|
||||||
s = buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ToString(std::string & s, long value)
|
|
||||||
{
|
|
||||||
static char buffer[50];
|
|
||||||
|
|
||||||
sprintf(buffer, "%ld", value);
|
|
||||||
s = buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SetUrlSubjectFromSubject(Item & item)
|
|
||||||
{
|
|
||||||
std::string::iterator i;
|
|
||||||
|
|
||||||
item.url_subject.clear();
|
|
||||||
|
|
||||||
for(i = item.subject.begin(); i!=item.subject.end() ; ++i)
|
|
||||||
{
|
|
||||||
int c = ChangeLocalChar(*i);
|
|
||||||
|
|
||||||
if( (c >= 'a' && c <='z') ||
|
|
||||||
(c >= 'A' && c <='Z') ||
|
|
||||||
(c >= '0' && c <='9') ||
|
|
||||||
(c == '(' || c == ')' || c == '.' || c == ',' || c == '_' )
|
|
||||||
)
|
|
||||||
{
|
|
||||||
item.url_subject += c;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
item.url_subject += '_';
|
|
||||||
}
|
|
||||||
|
|
||||||
if( item.url_subject.empty() )
|
|
||||||
item.url_subject = "bez_nazwy";
|
|
||||||
else
|
|
||||||
if( item.url_subject[0] >= '0' && item.url_subject[0] <= '9' )
|
|
||||||
// url_subject must begin with a letter
|
|
||||||
item.url_subject.insert(item.url_subject.begin(), '_');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int polish_letters_simple[] =
|
|
||||||
{ 'a', 'A',
|
|
||||||
'c', 'C',
|
|
||||||
's', 'S',
|
|
||||||
'e', 'E',
|
|
||||||
'l', 'L',
|
|
||||||
'o', 'O',
|
|
||||||
'z', 'Z',
|
|
||||||
'z', 'Z',
|
|
||||||
'n', 'N', 0 }; // 0 - terminating
|
|
||||||
|
|
||||||
|
|
||||||
int polish_letters_iso88592[] =
|
|
||||||
{ 0xb1, 0xa1,
|
|
||||||
0xe6, 0xc6,
|
|
||||||
0xb6, 0xa6,
|
|
||||||
0xea, 0xca,
|
|
||||||
0xb3, 0xa3,
|
|
||||||
0xf3, 0xd3,
|
|
||||||
0xbf, 0xaf,
|
|
||||||
0xbc, 0xac,
|
|
||||||
0xf1, 0xd1, 0 };
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ChangeLocalChar(unsigned char c)
|
|
||||||
{
|
|
||||||
// if( language == polish_iso88592 )
|
|
||||||
|
|
||||||
for(int i = 0 ; polish_letters_iso88592[i] ; ++i)
|
|
||||||
{
|
|
||||||
if( polish_letters_simple[i] == 0 )
|
|
||||||
{
|
|
||||||
log << log1 << "localization tables don't have the same size" << logend;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( polish_letters_iso88592[i] == c )
|
|
||||||
return polish_letters_simple[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void HtmlSpecial(std::ostringstream & out, const std::string & in)
|
|
||||||
{
|
|
||||||
std::string::const_iterator i;
|
|
||||||
|
|
||||||
for(i = in.begin() ; i != in.end() ; ++i)
|
|
||||||
{
|
|
||||||
if( *i == '<' )
|
|
||||||
out << "<";
|
|
||||||
else
|
|
||||||
if( *i == '>' )
|
|
||||||
out << ">";
|
|
||||||
else
|
|
||||||
out << *i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string HtmlSpecial(const std::string & in)
|
|
||||||
{
|
|
||||||
std::ostringstream out;
|
|
||||||
|
|
||||||
HtmlSpecial(out, in);
|
|
||||||
|
|
||||||
return out.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfilemisc
|
|
||||||
#define headerfilemisc
|
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include "log.h"
|
|
||||||
#include "item.h"
|
|
||||||
|
|
||||||
#define MAJOR_VER 0
|
|
||||||
#define MINOR_VER 1
|
|
||||||
#define REVISION_VER 0
|
|
||||||
|
|
||||||
|
|
||||||
void ToString(std::string & s, int value);
|
|
||||||
void ToString(std::string & s, long value);
|
|
||||||
void SetUrlSubjectFromSubject(Item & item);
|
|
||||||
int ChangeLocalChar(unsigned char c);
|
|
||||||
void HtmlSpecial(std::ostringstream & out, const std::string & in);
|
|
||||||
std::string HtmlSpecial(const std::string & in);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfilepostparser
|
|
||||||
#define headerfilepostparser
|
|
||||||
|
|
||||||
#include <fcgiapp.h>
|
|
||||||
#include <string>
|
|
||||||
#include "httpsimpleparser.h"
|
|
||||||
#include "requesttypes.h"
|
|
||||||
|
|
||||||
|
|
||||||
class PostParser : public HttpSimpleParser
|
|
||||||
{
|
|
||||||
|
|
||||||
FCGX_Stream * in;
|
|
||||||
PostTable & post_table;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
|
|
||||||
virtual int GetChar()
|
|
||||||
{
|
|
||||||
return FCGX_GetChar(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
virtual void Parameter(std::string & name, std::string & value)
|
|
||||||
{
|
|
||||||
std::pair<PostTable::iterator, bool> res = post_table.insert( std::make_pair(name, value) );
|
|
||||||
|
|
||||||
log << log2 << "Method POST, name: \"" << name << "\", value: \"" << value << "\"";
|
|
||||||
|
|
||||||
if( res.second == false )
|
|
||||||
log << log2 << " (skipped)";
|
|
||||||
|
|
||||||
log << log2 << logend;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
PostParser(FCGX_Stream * in_, PostTable & post_table_) : in(in_), post_table(post_table_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,374 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "request.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Request::Request()
|
|
||||||
{
|
|
||||||
Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Request::Clear()
|
|
||||||
{
|
|
||||||
// warning: don't clear in, out, err, env
|
|
||||||
|
|
||||||
get_table.clear();
|
|
||||||
post_table.clear();
|
|
||||||
cookie_table.clear();
|
|
||||||
|
|
||||||
method = none;
|
|
||||||
|
|
||||||
headers.str("");
|
|
||||||
page.str("");
|
|
||||||
debug.str("");
|
|
||||||
|
|
||||||
env_request_method = 0;
|
|
||||||
env_request_uri = 0;
|
|
||||||
env_http_cookie = 0;
|
|
||||||
|
|
||||||
session = 0;
|
|
||||||
|
|
||||||
result = err404; // tutaj moze cos lepszego, cos w stylu 'not implemented'
|
|
||||||
|
|
||||||
dir = -1;
|
|
||||||
cur_dir_table.clear();
|
|
||||||
item_table.clear();
|
|
||||||
dir_table.clear();
|
|
||||||
|
|
||||||
item.Clear();
|
|
||||||
str.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Request::CopyFirstItem()
|
|
||||||
{
|
|
||||||
if( !request.item_table.empty() )
|
|
||||||
request.item = request.item_table[0];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
request.item.Clear();
|
|
||||||
|
|
||||||
log << log1 << "Request::CopyFirstItem: item_table is empty" << logend;
|
|
||||||
request.result = err_internal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// value can be null
|
|
||||||
void Request::SetCookie(const char * name, const char * value)
|
|
||||||
{
|
|
||||||
request.headers << "Set-Cookie: " << name << "=";
|
|
||||||
|
|
||||||
if( value && value[0]!=0 )
|
|
||||||
request.headers << value;
|
|
||||||
else
|
|
||||||
request.headers << "\"\"";
|
|
||||||
|
|
||||||
request.headers << "; path=/\r\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Request::SetCookie(const char * name, long value)
|
|
||||||
{
|
|
||||||
request.headers << "Set-Cookie: " << name << "=" << value << "; path=/\r\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Request::IsPostVar(const char * var)
|
|
||||||
{
|
|
||||||
PostTable::iterator p;
|
|
||||||
|
|
||||||
p = post_table.find(var);
|
|
||||||
|
|
||||||
if( p == post_table.end() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string & Request::PostVar(const char * var)
|
|
||||||
{
|
|
||||||
PostTable::iterator p;
|
|
||||||
|
|
||||||
p = post_table.find(var);
|
|
||||||
|
|
||||||
if( p == post_table.end() )
|
|
||||||
throw Error();
|
|
||||||
|
|
||||||
return p->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
void Request::PrintGetTable()
|
|
||||||
{
|
|
||||||
debug << "get_table: " << get_table.size() << "\n";
|
|
||||||
|
|
||||||
for(GetTable::iterator i = get_table.begin() ; i != get_table.end() ; ++i)
|
|
||||||
debug << " \"" << *i << "\"\n";
|
|
||||||
|
|
||||||
debug << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Request::PrintEnv()
|
|
||||||
{
|
|
||||||
char ** e;
|
|
||||||
|
|
||||||
debug << "environment variables:\n";
|
|
||||||
|
|
||||||
for( e = env ; *e ; ++e )
|
|
||||||
debug << ' ' << *e << "\n";
|
|
||||||
|
|
||||||
debug << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Request::PrintIn()
|
|
||||||
{
|
|
||||||
char buf[100];
|
|
||||||
int buf_len = sizeof(buf) / sizeof(char);
|
|
||||||
int len;
|
|
||||||
|
|
||||||
debug << "fcgi input:\n";
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
len = FCGX_GetStr(buf, buf_len - 1, in);
|
|
||||||
|
|
||||||
if( len != 0 )
|
|
||||||
{
|
|
||||||
buf[len] = 0;
|
|
||||||
debug << buf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while( len == buf_len - 1 );
|
|
||||||
|
|
||||||
debug << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Request::ReadEnvVariables()
|
|
||||||
{
|
|
||||||
// we store that values because FCGX_GetParam has O(n) complexity
|
|
||||||
// with this variables (env_*) we have O(1)
|
|
||||||
|
|
||||||
env_request_method = FCGX_GetParam("REQUEST_METHOD", env);
|
|
||||||
env_request_uri = FCGX_GetParam("REQUEST_URI", env);
|
|
||||||
env_http_cookie = FCGX_GetParam("HTTP_COOKIE", env);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Request::CheckMethod()
|
|
||||||
{
|
|
||||||
method = none;
|
|
||||||
|
|
||||||
if( !env_request_method )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( env_request_method[0] == 'G' )
|
|
||||||
method = get;
|
|
||||||
else
|
|
||||||
if( env_request_method[0] == 'P' )
|
|
||||||
method = post;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Request::ReadParameters()
|
|
||||||
{
|
|
||||||
// some parameters (get) we have always
|
|
||||||
// if( method == get )
|
|
||||||
{
|
|
||||||
GetParser get_parser(env_request_uri, get_table);
|
|
||||||
get_parser.Parse();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( method == post )
|
|
||||||
{
|
|
||||||
PostParser post_parser(in, post_table);
|
|
||||||
post_parser.Parse();
|
|
||||||
}
|
|
||||||
|
|
||||||
CookieParser cookie_parser(env_http_cookie, cookie_table);
|
|
||||||
cookie_parser.Parse();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// reading everything
|
|
||||||
void Request::Read()
|
|
||||||
{
|
|
||||||
ReadEnvVariables();
|
|
||||||
CheckMethod();
|
|
||||||
ReadParameters();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Request::SendAll()
|
|
||||||
{
|
|
||||||
if( result == redirect )
|
|
||||||
{
|
|
||||||
FCGX_PutS("Status: 301 Moved Permanently\r\n", out);
|
|
||||||
FCGX_FPrintF(out, "Location: %s\r\n", str.c_str());
|
|
||||||
|
|
||||||
log << log2 << "Redirect into: " << str << logend;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FCGX_PutS("Status: 200 OK\r\n", out);
|
|
||||||
FCGX_PutS("Content-Type: Text/Html\r\n", out);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FCGX_PutS(headers.str().c_str(), out);
|
|
||||||
FCGX_PutS("\r\n", out);
|
|
||||||
|
|
||||||
|
|
||||||
if( result == redirect )
|
|
||||||
// if there is a redirect we do not send a content
|
|
||||||
return;
|
|
||||||
|
|
||||||
FCGX_PutS(page.str().c_str(), out);
|
|
||||||
|
|
||||||
const std::string & d = debug.str();
|
|
||||||
|
|
||||||
if( !d.empty() )
|
|
||||||
{
|
|
||||||
FCGX_PutS("\n<!--\n", out);
|
|
||||||
FCGX_PutS(d.c_str(), out);
|
|
||||||
FCGX_PutS("\n-->\n", out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char Request::tohex(unsigned char polowa)
|
|
||||||
{
|
|
||||||
// polowa z zakresu 0-15
|
|
||||||
polowa = polowa & 0xf;
|
|
||||||
|
|
||||||
if(polowa<10)
|
|
||||||
polowa += '0';
|
|
||||||
else
|
|
||||||
polowa = polowa - 10 + 'A';
|
|
||||||
|
|
||||||
return polowa;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// cala wartosc zapisywana jest w postaci hex
|
|
||||||
string Request::ToHex(const string & dane)
|
|
||||||
{
|
|
||||||
string wynik;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
|
|
||||||
for(i=0 ; i<dane.length() ; ++i)
|
|
||||||
{
|
|
||||||
wynik += tohex(dane[i] >> 4);
|
|
||||||
wynik += tohex(dane[i] & 0xf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return wynik;
|
|
||||||
}
|
|
||||||
|
|
||||||
string Request::HexToString(const string & dane)
|
|
||||||
{
|
|
||||||
string wynik;
|
|
||||||
unsigned int i;
|
|
||||||
unsigned char znak,znak1,znak2;
|
|
||||||
|
|
||||||
if(dane.length()==0)
|
|
||||||
return wynik;
|
|
||||||
|
|
||||||
for(i=0 ; i<dane.length()-1 ; i+=2)
|
|
||||||
{
|
|
||||||
znak1 = parsujhex(dane[i]);
|
|
||||||
znak2 = parsujhex(dane[i+1]);
|
|
||||||
|
|
||||||
znak = (znak1 << 4) + znak2;
|
|
||||||
|
|
||||||
wynik += znak;
|
|
||||||
}
|
|
||||||
|
|
||||||
return wynik;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string Request::ToUrl(const string & dane)
|
|
||||||
{
|
|
||||||
string wynik;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
|
|
||||||
for(i=0 ; i<dane.length() ; ++i)
|
|
||||||
{
|
|
||||||
if( (dane[i]>='a' && dane[i]<='z') ||
|
|
||||||
(dane[i]>='A' && dane[i]<='Z') ||
|
|
||||||
(dane[i]>='0' && dane[i]<='9') ||
|
|
||||||
dane[i]=='_' )
|
|
||||||
{
|
|
||||||
wynik += dane[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wynik += '%';
|
|
||||||
|
|
||||||
wynik += tohex(dane[i] >> 4);
|
|
||||||
wynik += tohex(dane[i] & 0xf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return wynik;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-116
@@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfilerequest
|
|
||||||
#define headerfilerequest
|
|
||||||
|
|
||||||
#include <fcgiapp.h>
|
|
||||||
#include <sstream>
|
|
||||||
#include <vector>
|
|
||||||
#include "requesttypes.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "session.h"
|
|
||||||
|
|
||||||
#include "getparser.h"
|
|
||||||
#include "postparser.h"
|
|
||||||
#include "cookieparser.h"
|
|
||||||
#include "item.h"
|
|
||||||
#include "error.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct Request
|
|
||||||
{
|
|
||||||
FCGX_Stream * in, * out, * err;
|
|
||||||
FCGX_ParamArray env; // defined as 'char **'
|
|
||||||
|
|
||||||
|
|
||||||
enum Method { get, post, none } method;
|
|
||||||
|
|
||||||
|
|
||||||
// headers, page and debug
|
|
||||||
std::ostringstream headers, page, debug;
|
|
||||||
|
|
||||||
|
|
||||||
GetTable get_table;
|
|
||||||
PostTable post_table;
|
|
||||||
CookieTable cookie_table;
|
|
||||||
|
|
||||||
const char * env_request_method;
|
|
||||||
const char * env_request_uri;
|
|
||||||
const char * env_http_cookie;
|
|
||||||
|
|
||||||
// current session
|
|
||||||
// is set after calling session_manager.SetSession()
|
|
||||||
Session * session;
|
|
||||||
|
|
||||||
|
|
||||||
// 'done_status' is set if 'done' is different than 'nothing'
|
|
||||||
Error done_status;
|
|
||||||
|
|
||||||
// what to do
|
|
||||||
enum Result { err_internal, err404, show_dir, show_item, show_item_by_id, add_item, edit_item, del_item, del_item_confirm, confirm, redirect, logout } result; // zamienic na to_do
|
|
||||||
//Item item; // bedziemy uzywac tego, item_id i item_url_subject wywalic
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// current directory e.g. /foo/bar
|
|
||||||
std::vector<Item> cur_dir_table;
|
|
||||||
|
|
||||||
// id of the last directory (bar) or -1
|
|
||||||
long dir;
|
|
||||||
|
|
||||||
// items in the current directory
|
|
||||||
// maybe without contents?
|
|
||||||
std::vector<Item> item_table;
|
|
||||||
|
|
||||||
// directories in the current directory
|
|
||||||
std::vector<Item> dir_table;
|
|
||||||
|
|
||||||
// this item is used for many purposes such as editing, adding an item etc.
|
|
||||||
Item item;
|
|
||||||
|
|
||||||
// this string is used for many purposes such as redirecting
|
|
||||||
std::string str;
|
|
||||||
|
|
||||||
// for debugging
|
|
||||||
void PrintGetTable();
|
|
||||||
void PrintEnv();
|
|
||||||
void PrintIn();
|
|
||||||
|
|
||||||
Request();
|
|
||||||
void Clear();
|
|
||||||
|
|
||||||
|
|
||||||
void SetCookie(const char * name, const char * value);
|
|
||||||
void SetCookie(const char * name, long value);
|
|
||||||
|
|
||||||
bool IsPostVar(const char * var);
|
|
||||||
std::string & PostVar(const char * var); // with a throw
|
|
||||||
|
|
||||||
|
|
||||||
// item_table[0] -> item
|
|
||||||
void CopyFirstItem();
|
|
||||||
|
|
||||||
|
|
||||||
void ReadEnvVariables();
|
|
||||||
void CheckMethod();
|
|
||||||
void ReadParameters();
|
|
||||||
void Read();
|
|
||||||
void SendAll();
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern Request request;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "requestcontroller.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
RequestController::RequestController()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool RequestController::Init()
|
|
||||||
{
|
|
||||||
const char * sock = data.fcgi_socket.c_str();
|
|
||||||
|
|
||||||
unlink(sock);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int s = FCGX_OpenSocket(sock, 10);
|
|
||||||
|
|
||||||
if( s < 0 )
|
|
||||||
{
|
|
||||||
log << log1 << "An error during creating a socket" << logend;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
chmod(sock, data.fcgi_socket_chmod);
|
|
||||||
|
|
||||||
passwd * pw = getpwnam(data.fcgi_socket_user.c_str());
|
|
||||||
|
|
||||||
if( !pw )
|
|
||||||
{
|
|
||||||
log << log1 << "There is no user: " << data.fcgi_socket_user << logend;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
group * gr = getgrnam(data.fcgi_socket_group.c_str());
|
|
||||||
|
|
||||||
if( !gr )
|
|
||||||
{
|
|
||||||
log << log1 << "There is no group: " << data.fcgi_socket_group << logend;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
chown(sock, pw->pw_uid, gr->gr_gid);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if( setuid(pw->pw_uid) < 0 )
|
|
||||||
{
|
|
||||||
log << log1 << "I can't change the user into: " << data.fcgi_socket_user << logend;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
if( setgid(gr->gr_gid) < 0 )
|
|
||||||
{
|
|
||||||
int e = errno;
|
|
||||||
|
|
||||||
log << log1 << "I can't change the group into: " << data.fcgi_socket_group << " " << gr->gr_gid << logend;
|
|
||||||
log << log1 << "errno: " << e << logend;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
dup2(s, 0);
|
|
||||||
|
|
||||||
if( !data.log_stdout )
|
|
||||||
close(1);
|
|
||||||
|
|
||||||
close(2);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
data.dir.ReadDirs();
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
if( !content.Init() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void RequestController::Loop()
|
|
||||||
{
|
|
||||||
while( FCGX_Accept(&request.in, &request.out, &request.err, &request.env) == 0 )
|
|
||||||
{
|
|
||||||
log << log2 << "start request" << logend;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
request.Clear();
|
|
||||||
request.Read();
|
|
||||||
|
|
||||||
session_manager.SetSession(); // setting request.session as well
|
|
||||||
request.session->CheckTimers();
|
|
||||||
|
|
||||||
content.Make();
|
|
||||||
request.SendAll();
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(const std::exception & e)
|
|
||||||
{
|
|
||||||
log << log1 << "uncaught std exception: " << e.what() << logend;
|
|
||||||
}
|
|
||||||
catch(const Error & e)
|
|
||||||
{
|
|
||||||
log << log1 << "uncaught exception: Error: " << e << logend;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
log << log1 << "uncaught exception" << logend;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
log << log2 << "end request" << logend;
|
|
||||||
log << log2 << "---------------------------------------------------------------------------------" << logend;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfilerequestcontroller
|
|
||||||
#define headerfilerequestcontroller
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <grp.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "data.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "request.h"
|
|
||||||
#include "content.h"
|
|
||||||
#include "sessionmanager.h"
|
|
||||||
#include "postparser.h"
|
|
||||||
#include "cookieparser.h"
|
|
||||||
|
|
||||||
|
|
||||||
class RequestController
|
|
||||||
{
|
|
||||||
Content content;
|
|
||||||
SessionManager session_manager;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
RequestController();
|
|
||||||
|
|
||||||
bool Init();
|
|
||||||
void Loop();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfilerequesttypes
|
|
||||||
#define headerfilerequesttypes
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
|
|
||||||
// some global types used by Request class
|
|
||||||
typedef std::vector<std::string> GetTable;
|
|
||||||
typedef std::map<std::string, std::string> PostTable;
|
|
||||||
typedef std::map<std::string, std::string> CookieTable;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "session.h"
|
|
||||||
|
|
||||||
|
|
||||||
Session::Session()
|
|
||||||
{
|
|
||||||
Clear();
|
|
||||||
|
|
||||||
time = std::time(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Session::Clear()
|
|
||||||
{
|
|
||||||
id = 0;
|
|
||||||
time = 0;
|
|
||||||
is_logged = false;
|
|
||||||
user_id = 0;
|
|
||||||
user.clear();
|
|
||||||
done = Done::none;
|
|
||||||
done_status = Error::ok;
|
|
||||||
item.Clear();
|
|
||||||
done_timer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Session::operator==(const Session & s) const
|
|
||||||
{
|
|
||||||
return id == s.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Session::operator<(const Session & s) const
|
|
||||||
{
|
|
||||||
return id < s.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Session::DecTimer(int & timer)
|
|
||||||
{
|
|
||||||
if( timer == 0 )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
--timer;
|
|
||||||
|
|
||||||
if( timer == 0 )
|
|
||||||
return true; // we must clear our variables
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Session::CheckTimers()
|
|
||||||
{
|
|
||||||
if( DecTimer(done_timer) )
|
|
||||||
{
|
|
||||||
done = Done::none;
|
|
||||||
done_status = Error::ok;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfilecoresession
|
|
||||||
#define headerfilecoresession
|
|
||||||
|
|
||||||
#include <ctime>
|
|
||||||
#include "requesttypes.h"
|
|
||||||
#include "error.h"
|
|
||||||
#include "item.h"
|
|
||||||
#include "done.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Session
|
|
||||||
{
|
|
||||||
// 0 - means that there is no session
|
|
||||||
long id;
|
|
||||||
int time;
|
|
||||||
|
|
||||||
bool is_logged;
|
|
||||||
long user_id; // logged user
|
|
||||||
|
|
||||||
std::string user; // user name
|
|
||||||
|
|
||||||
// what is done
|
|
||||||
Done done;
|
|
||||||
Error done_status;
|
|
||||||
|
|
||||||
int done_timer;
|
|
||||||
|
|
||||||
|
|
||||||
// used for many purposes, depending on 'done'
|
|
||||||
Item item;
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------
|
|
||||||
|
|
||||||
Session();
|
|
||||||
virtual void Clear();
|
|
||||||
bool operator==(const Session & s) const;
|
|
||||||
bool operator<(const Session & s) const;
|
|
||||||
bool DecTimer(int & timer);
|
|
||||||
void CheckTimers();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sessionmanager.h"
|
|
||||||
|
|
||||||
|
|
||||||
bool SessionManager::IsSession(long s)
|
|
||||||
{
|
|
||||||
SessionTable::iterator i;
|
|
||||||
|
|
||||||
Session temp;
|
|
||||||
|
|
||||||
temp.id = s;
|
|
||||||
|
|
||||||
i = session_table.find(temp);
|
|
||||||
|
|
||||||
if( i == session_table.end() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
long SessionManager::CreateSessionId()
|
|
||||||
{
|
|
||||||
long id;
|
|
||||||
|
|
||||||
// make sure to call std::srand() somewhere at the beginning
|
|
||||||
// id must be != 0 (0 is reserved)
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if( sizeof(long) == 8 )
|
|
||||||
{
|
|
||||||
id = ((unsigned long)std::rand()) << 32 + std::rand();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
id = std::rand();
|
|
||||||
}
|
|
||||||
|
|
||||||
id += std::time(0);
|
|
||||||
|
|
||||||
if( id < 0 )
|
|
||||||
id = -id;
|
|
||||||
|
|
||||||
}
|
|
||||||
while( id == 0 ); // 0 reserved for a temporary session
|
|
||||||
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SessionManager::CreateTemporarySession()
|
|
||||||
{
|
|
||||||
Session s;
|
|
||||||
|
|
||||||
s.id = 0;
|
|
||||||
SessionTable::iterator i = session_table.find( s ); // looking for id=0
|
|
||||||
|
|
||||||
if( i == session_table.end() )
|
|
||||||
{
|
|
||||||
std::pair<SessionTable::iterator,bool> res = session_table.insert(s);
|
|
||||||
request.session = const_cast<Session*>( &(*res.first) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
request.session = const_cast<Session*>( &(*i) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SessionManager::CreateSession()
|
|
||||||
{
|
|
||||||
Session s;
|
|
||||||
int attempts = 100;
|
|
||||||
|
|
||||||
for( ; attempts > 0 ; --attempts )
|
|
||||||
{
|
|
||||||
s.id = CreateSessionId();
|
|
||||||
|
|
||||||
std::pair<SessionTable::iterator,bool> res = session_table.insert(s);
|
|
||||||
|
|
||||||
if( res.second == true )
|
|
||||||
{
|
|
||||||
// the insertion took place
|
|
||||||
|
|
||||||
request.session = const_cast<Session*>( &(*res.first) );
|
|
||||||
request.SetCookie(data.http_session_id_name.c_str(), request.session->id);
|
|
||||||
log << log1 << "created a new session: " << s.id << logend;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// there is a problem with generating a new session id
|
|
||||||
// we do not set a session cookie
|
|
||||||
CreateTemporarySession();
|
|
||||||
log << log1 << "cannot create a session id (temporary used: with id 0)" << logend;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SessionManager::SetSession()
|
|
||||||
{
|
|
||||||
CookieTable::iterator i = request.cookie_table.find(data.http_session_id_name);
|
|
||||||
|
|
||||||
if( i == request.cookie_table.end() )
|
|
||||||
{
|
|
||||||
CreateSession();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Session temp;
|
|
||||||
temp.id = atol(i->second.c_str());
|
|
||||||
SessionTable::iterator s = session_table.find(temp);
|
|
||||||
|
|
||||||
if( s != session_table.end() )
|
|
||||||
{
|
|
||||||
// that session is in the table
|
|
||||||
request.session = const_cast<Session*>( &(*s) );
|
|
||||||
log << log1 << "session: " << s->id << logend;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// there is no such a session
|
|
||||||
// deleting the old cookie
|
|
||||||
request.cookie_table.erase(i);
|
|
||||||
|
|
||||||
// and creating a new one
|
|
||||||
CreateSession();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// request.session is set now
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfilesessionmanager
|
|
||||||
#define headerfilesessionmanager
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
#include <ctime>
|
|
||||||
|
|
||||||
#include "request.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "data.h"
|
|
||||||
#include "session.h"
|
|
||||||
#include "db.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SessionManager
|
|
||||||
{
|
|
||||||
// !! zamienic na map
|
|
||||||
typedef std::set<Session> SessionTable;
|
|
||||||
|
|
||||||
SessionTable session_table;
|
|
||||||
|
|
||||||
bool IsSession(long s);
|
|
||||||
|
|
||||||
long CreateSessionId();
|
|
||||||
void CreateTemporarySession();
|
|
||||||
void CreateSession();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
void SetSession();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,542 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "templates.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace TemplatesFunctions
|
|
||||||
{
|
|
||||||
Pattern pat_index;
|
|
||||||
Pattern pat_item;
|
|
||||||
Pattern pat_dir;
|
|
||||||
Pattern pat_item_add_edit;
|
|
||||||
Pattern pat_item_del_confirm;
|
|
||||||
Pattern pat_err_404;
|
|
||||||
Pattern pat_err_internal;
|
|
||||||
|
|
||||||
Functions functions;
|
|
||||||
|
|
||||||
|
|
||||||
void language(Info & i)
|
|
||||||
{
|
|
||||||
// at the moment only Polish language
|
|
||||||
i.out << "pl";
|
|
||||||
}
|
|
||||||
|
|
||||||
void title(Info & i)
|
|
||||||
{
|
|
||||||
i.out << "";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void charset(Info & i)
|
|
||||||
{
|
|
||||||
i.out << "iso-8859-2";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void version_major(Info & i)
|
|
||||||
{
|
|
||||||
i.out << MAJOR_VER;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void version_minor(Info & i)
|
|
||||||
{
|
|
||||||
i.out << MINOR_VER;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void version_revision(Info & i)
|
|
||||||
{
|
|
||||||
i.out << REVISION_VER;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void content(Info & i)
|
|
||||||
{
|
|
||||||
Pattern * p;
|
|
||||||
|
|
||||||
switch( request.result )
|
|
||||||
{
|
|
||||||
case Request::add_item:
|
|
||||||
case Request::edit_item:
|
|
||||||
p = &pat_item_add_edit;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Request::show_dir:
|
|
||||||
p = &pat_dir;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Request::show_item:
|
|
||||||
p = &pat_item;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Request::del_item_confirm:
|
|
||||||
p = &pat_item_del_confirm;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Request::err_internal:
|
|
||||||
p = &pat_err_internal;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Request::err404:
|
|
||||||
default:
|
|
||||||
p = &pat_err_404;
|
|
||||||
}
|
|
||||||
|
|
||||||
Generator gen(i.out, *p, functions);
|
|
||||||
|
|
||||||
gen.Generate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void base_url(Info & i)
|
|
||||||
{
|
|
||||||
i.out << data.base_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void current_url(Info & i)
|
|
||||||
{
|
|
||||||
if( request.env_request_uri )
|
|
||||||
i.out << request.env_request_uri;
|
|
||||||
else
|
|
||||||
base_url(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void user_logged(Info & i)
|
|
||||||
{
|
|
||||||
i.result = request.session->is_logged;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void user(Info & i)
|
|
||||||
{
|
|
||||||
i.out << request.session->user;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void item_id(Info & i)
|
|
||||||
{
|
|
||||||
i.out << request.item.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void item_subject(Info & i)
|
|
||||||
{
|
|
||||||
i.out << HtmlSpecial(request.item.subject);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void item_content(Info & i)
|
|
||||||
{
|
|
||||||
//i.out << HtmlSpecial(request.item.content);
|
|
||||||
i.out << request.item.content;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void item_url_subject(Info & i)
|
|
||||||
{
|
|
||||||
i.out << request.item.url_subject;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void item_dir(Info & i)
|
|
||||||
{
|
|
||||||
std::string path;
|
|
||||||
|
|
||||||
if( data.dir.MakePath(request.item.parent_id, path) )
|
|
||||||
{
|
|
||||||
i.out << path;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i.out << "problem with generating a path";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ---------
|
|
||||||
|
|
||||||
|
|
||||||
void old_item_id(Info & i)
|
|
||||||
{
|
|
||||||
i.out << request.session->item.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void old_item_subject(Info & i)
|
|
||||||
{
|
|
||||||
i.out << HtmlSpecial(request.session->item.subject);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void old_item_content(Info & i)
|
|
||||||
{
|
|
||||||
//i.out << HtmlSpecial(request.session->item.content);
|
|
||||||
i.out << request.session->item.content;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void old_item_url_subject(Info & i)
|
|
||||||
{
|
|
||||||
i.out << request.session->item.url_subject;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void old_item_dir(Info & i)
|
|
||||||
{
|
|
||||||
std::string path;
|
|
||||||
|
|
||||||
if( data.dir.MakePath(request.session->item.parent_id, path) )
|
|
||||||
{
|
|
||||||
i.out << path;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i.out << "problem with generating a path";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----
|
|
||||||
|
|
||||||
void full_dir(Info & i)
|
|
||||||
{
|
|
||||||
std::vector<Item>::size_type a;
|
|
||||||
|
|
||||||
for(a=0 ; a<request.cur_dir_table.size() ; ++a)
|
|
||||||
{
|
|
||||||
i.out << request.cur_dir_table[a].url_subject << '/';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<Item>::size_type item_index, dir_index;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void dir_items(Info & i)
|
|
||||||
{
|
|
||||||
if( i.iter >= (int)request.dir_table.size() )
|
|
||||||
{
|
|
||||||
i.result = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i.result = true;
|
|
||||||
dir_index = i.iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dir_subject2(Info & i)
|
|
||||||
{
|
|
||||||
if( dir_index < request.dir_table.size() )
|
|
||||||
{
|
|
||||||
if( request.dir_table[dir_index].subject.empty() )
|
|
||||||
i.out << "bez nazwy";
|
|
||||||
else
|
|
||||||
HtmlSpecial(i.out, request.dir_table[dir_index].subject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dir_url_subject2(Info & i)
|
|
||||||
{
|
|
||||||
if( dir_index < request.dir_table.size() )
|
|
||||||
{
|
|
||||||
HtmlSpecial(i.out, request.dir_table[dir_index].url_subject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void items(Info & i) // zamienic na fitems !!
|
|
||||||
{
|
|
||||||
if( i.iter >= (int)request.item_table.size() )
|
|
||||||
{
|
|
||||||
i.result = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i.result = true;
|
|
||||||
item_index = i.iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void item_subject2(Info & i)
|
|
||||||
{
|
|
||||||
if( item_index < request.item_table.size() )
|
|
||||||
{
|
|
||||||
if( request.item_table[item_index].subject.empty() )
|
|
||||||
i.out << "bez nazwy";
|
|
||||||
else
|
|
||||||
HtmlSpecial(i.out, request.item_table[item_index].subject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void item_url_subject2(Info & i)
|
|
||||||
{
|
|
||||||
if( item_index < request.item_table.size() )
|
|
||||||
HtmlSpecial(i.out, request.item_table[item_index].url_subject);
|
|
||||||
}
|
|
||||||
|
|
||||||
void item_content2(Info & i)
|
|
||||||
{
|
|
||||||
if( item_index < request.item_table.size() )
|
|
||||||
//HtmlSpecial(i.out, request.item_table[item_index].content);
|
|
||||||
i.out << request.item_table[item_index].content;
|
|
||||||
}
|
|
||||||
|
|
||||||
void item_id2(Info & i)
|
|
||||||
{
|
|
||||||
if( item_index < request.item_table.size() )
|
|
||||||
i.out << request.item_table[item_index].id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void incorrect_dir(Info & i)
|
|
||||||
{
|
|
||||||
if( request.session->done_status == Error::incorrect_dir )
|
|
||||||
i.result = true;
|
|
||||||
else
|
|
||||||
i.result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<Item>::size_type current_dir_index;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void fcurrent_dir(Info & i)
|
|
||||||
{
|
|
||||||
if( i.iter < (int)request.cur_dir_table.size() )
|
|
||||||
{
|
|
||||||
current_dir_index = i.iter;
|
|
||||||
i.result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
i.result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void current_dir_part_name(Info & i)
|
|
||||||
{
|
|
||||||
if( current_dir_index < request.cur_dir_table.size() )
|
|
||||||
i.out << request.cur_dir_table[current_dir_index].subject;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void current_dir_part_url(Info & i)
|
|
||||||
{
|
|
||||||
std::vector<Item>::size_type a;
|
|
||||||
|
|
||||||
i.out << data.base_url;
|
|
||||||
|
|
||||||
for(a = 0 ; a <= current_dir_index && a < request.cur_dir_table.size() ; ++a)
|
|
||||||
{
|
|
||||||
i.out << request.cur_dir_table[a].url_subject << '/';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void edit_item(Info & i)
|
|
||||||
{
|
|
||||||
i.result = request.result == Request::edit_item;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void added_item(Info &i)
|
|
||||||
{
|
|
||||||
i.result = request.session->done == Done::added_item;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void edited_item(Info &i)
|
|
||||||
{
|
|
||||||
i.result = request.session->done == Done::edited_item;
|
|
||||||
}
|
|
||||||
|
|
||||||
void deleted_item(Info &i)
|
|
||||||
{
|
|
||||||
i.result = request.session->done == Done::deleted_item;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// zostawic tylko jedna funkcje done_with_errors (bedzie uzywana do roznych celow) !!
|
|
||||||
void deleted_item_errors(Info & i)
|
|
||||||
{
|
|
||||||
i.result = request.session->done_status != Error::ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void done_with_errors(Info & i)
|
|
||||||
{
|
|
||||||
i.result = request.session->done_status != Error::ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void done_status(Info & i)
|
|
||||||
{
|
|
||||||
i.out << static_cast<int>( request.session->done_status );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void fitems_in_dir(Info & i)
|
|
||||||
{
|
|
||||||
// i.out << "abc: " << variables["fitems_directory"];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void loggedout(Info & i)
|
|
||||||
{
|
|
||||||
i.result = request.session->done == Done::loggedout;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace TemplatesFunctions
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Templates::CreateFunctions()
|
|
||||||
{
|
|
||||||
using namespace TemplatesFunctions;
|
|
||||||
|
|
||||||
functions.Clear();
|
|
||||||
|
|
||||||
functions.Insert("language", language);
|
|
||||||
functions.Insert("title", title);
|
|
||||||
functions.Insert("charset", charset);
|
|
||||||
functions.Insert("content", content);
|
|
||||||
functions.Insert("version_major", version_major);
|
|
||||||
functions.Insert("version_minor", version_minor);
|
|
||||||
functions.Insert("version_revision", version_revision);
|
|
||||||
functions.Insert("base_url", base_url);
|
|
||||||
functions.Insert("current_url", current_url);
|
|
||||||
functions.Insert("user_logged", user_logged);
|
|
||||||
functions.Insert("user", user);
|
|
||||||
|
|
||||||
functions.Insert("item_id", item_id);
|
|
||||||
functions.Insert("item_subject", item_subject);
|
|
||||||
functions.Insert("item_content", item_content);
|
|
||||||
functions.Insert("item_url_subject", item_url_subject);
|
|
||||||
functions.Insert("item_dir", item_dir);
|
|
||||||
|
|
||||||
functions.Insert("old_item_id", old_item_id);
|
|
||||||
functions.Insert("old_item_subject", old_item_subject);
|
|
||||||
functions.Insert("old_item_content", old_item_content);
|
|
||||||
functions.Insert("old_item_url_subject", old_item_url_subject);
|
|
||||||
functions.Insert("old_item_dir", old_item_dir);
|
|
||||||
|
|
||||||
functions.Insert("dir_items", dir_items);
|
|
||||||
functions.Insert("items", items);
|
|
||||||
functions.Insert("item_subject2", item_subject2);
|
|
||||||
functions.Insert("dir_subject2", dir_subject2);
|
|
||||||
functions.Insert("full_dir", full_dir);
|
|
||||||
functions.Insert("dir_url_subject2", dir_url_subject2);
|
|
||||||
functions.Insert("item_url_subject2", item_url_subject2);
|
|
||||||
functions.Insert("item_content2", item_content2);
|
|
||||||
functions.Insert("item_id2", item_id2);
|
|
||||||
|
|
||||||
|
|
||||||
functions.Insert("edit_item", edit_item);
|
|
||||||
|
|
||||||
|
|
||||||
functions.Insert("incorrect_dir", incorrect_dir);
|
|
||||||
|
|
||||||
functions.Insert("fcurrent_dir", fcurrent_dir);
|
|
||||||
functions.Insert("current_dir_part_name", current_dir_part_name);
|
|
||||||
functions.Insert("current_dir_part_url", current_dir_part_url);
|
|
||||||
|
|
||||||
functions.Insert("added_item", added_item);
|
|
||||||
functions.Insert("edited_item", edited_item);
|
|
||||||
functions.Insert("deleted_item", deleted_item);
|
|
||||||
functions.Insert("loggedout", loggedout);
|
|
||||||
functions.Insert("deleted_item_errors", deleted_item_errors);
|
|
||||||
|
|
||||||
|
|
||||||
functions.Insert("done_with_errors", done_with_errors);
|
|
||||||
functions.Insert("done_status", done_status);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
functions.Insert("fitems_in_dir", fitems_in_dir);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Templates::Read()
|
|
||||||
{
|
|
||||||
using namespace TemplatesFunctions;
|
|
||||||
|
|
||||||
pat_index.Directory(data.templates);
|
|
||||||
pat_index.ParseFile(data.default_index);
|
|
||||||
|
|
||||||
pat_item.Directory(data.templates);
|
|
||||||
pat_item.ParseFile("item.html");
|
|
||||||
|
|
||||||
pat_dir.Directory(data.templates);
|
|
||||||
pat_dir.ParseFile("dir.html");
|
|
||||||
|
|
||||||
pat_item_add_edit.Directory(data.templates);
|
|
||||||
pat_item_add_edit.ParseFile("item_add_edit.html");
|
|
||||||
|
|
||||||
pat_err_404.Directory(data.templates);
|
|
||||||
pat_err_404.ParseFile("err_404.html");
|
|
||||||
|
|
||||||
pat_item_del_confirm.Directory(data.templates);
|
|
||||||
pat_item_del_confirm.ParseFile("item_del_confirm.html");
|
|
||||||
|
|
||||||
pat_err_internal.Directory(data.templates);
|
|
||||||
pat_err_internal.ParseFile("err_internal.html");
|
|
||||||
|
|
||||||
CreateFunctions();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Templates::Generate()
|
|
||||||
{
|
|
||||||
using namespace TemplatesFunctions;
|
|
||||||
|
|
||||||
// clear some variables (indexes for example)
|
|
||||||
item_index = 0;
|
|
||||||
current_dir_index = 0;
|
|
||||||
|
|
||||||
|
|
||||||
Generator generator(request.page, pat_index, functions);
|
|
||||||
|
|
||||||
generator.Generate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of CMSLU -- Content Management System like Unix
|
|
||||||
* and is not publicly distributed
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Tomasz Sowa
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef headerfiletemplates
|
|
||||||
#define headerfiletemplates
|
|
||||||
|
|
||||||
|
|
||||||
#include "../../ezc/src/ezc.h"
|
|
||||||
#include "data.h"
|
|
||||||
#include "request.h"
|
|
||||||
#include "item.h"
|
|
||||||
#include "db.h"
|
|
||||||
#include "error.h"
|
|
||||||
|
|
||||||
using namespace Ezc;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Templates
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
void Read();
|
|
||||||
void Generate();
|
|
||||||
|
|
||||||
void CreateFunctions();
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export CXX
|
||||||
|
export CXXFLAGS
|
||||||
|
export LDFLAGS
|
||||||
|
|
||||||
|
|
||||||
|
all: src
|
||||||
|
|
||||||
|
|
||||||
|
src: FORCE
|
||||||
|
$(MAKE) -C src
|
||||||
|
|
||||||
|
|
||||||
|
clean: FORCE
|
||||||
|
$(MAKE) -C src clean
|
||||||
|
|
||||||
|
|
||||||
|
depend: FORCE
|
||||||
|
$(MAKE) -C src depend
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FORCE:
|
||||||
|
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
sourcefiles:=$(shell find . -name "*.cpp")
|
||||||
|
objfiles:=$(patsubst %.cpp,%.o,$(sourcefiles))
|
||||||
|
GLOBAL_WORKING_DIR := $(shell pwd)/../../..
|
||||||
|
|
||||||
|
|
||||||
|
WINIX_NEEDED_MACROS = -DPT_HAS_MORM_LIBRARY \
|
||||||
|
-DEZC_HAS_MORM_LIBRARY \
|
||||||
|
-DMORM_HAS_EZC_LIBRARY
|
||||||
|
|
||||||
|
|
||||||
|
ifndef CXX
|
||||||
|
CXX = g++
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef ADDITIONAL_CXXFLAGS
|
||||||
|
ADDITIONAL_CXXFLAGS=-O2
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef ADDITIONAL_LDFLAGS
|
||||||
|
ADDITIONAL_LDFLAGS=-s
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef CXXFLAGS
|
||||||
|
# /usr/include/postgresql is in Linux distros (Alpine)
|
||||||
|
CXXFLAGS = -Wall -pedantic -std=c++20 $(ADDITIONAL_CXXFLAGS) \
|
||||||
|
-I/usr/local/include \
|
||||||
|
-I/usr/include/postgresql \
|
||||||
|
-I$(GLOBAL_WORKING_DIR)/winix/winixcli \
|
||||||
|
-I$(GLOBAL_WORKING_DIR)/pikotools/src \
|
||||||
|
-I$(GLOBAL_WORKING_DIR)/morm/src \
|
||||||
|
-I$(GLOBAL_WORKING_DIR)/ezc/src \
|
||||||
|
-I$(GLOBAL_WORKING_DIR)/tito/src \
|
||||||
|
$(WINIX_NEEDED_MACROS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
LDFLAGS = -L/usr/local/lib $(ADDITIONAL_LDFLAGS)
|
||||||
|
|
||||||
|
|
||||||
|
export CXX
|
||||||
|
export CXXFLAGS
|
||||||
|
export LDFLAGS
|
||||||
|
export GLOBAL_WORKING_DIR
|
||||||
|
export WINIX_NEEDED_MACROS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
progname = winix
|
||||||
|
|
||||||
|
|
||||||
|
all: $(progname)
|
||||||
|
|
||||||
|
|
||||||
|
$(progname): $(objfiles) pikotools morm ezc
|
||||||
|
$(CXX) -o $(progname) $(CXXFLAGS) $(LDFLAGS) $(objfiles) $(GLOBAL_WORKING_DIR)/ezc/src/ezc.a $(GLOBAL_WORKING_DIR)/morm/src/morm.a $(GLOBAL_WORKING_DIR)/pikotools/src/pikotools.a
|
||||||
|
|
||||||
|
|
||||||
|
%.o: %.cpp
|
||||||
|
$(CXX) -c $(CXXFLAGS) -o $@ $<
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: pikotools
|
||||||
|
.PHONY: morm
|
||||||
|
.PHONY: ezc
|
||||||
|
|
||||||
|
|
||||||
|
pikotools:
|
||||||
|
$(MAKE) -C ../../../pikotools
|
||||||
|
|
||||||
|
|
||||||
|
morm:
|
||||||
|
$(MAKE) -C ../../../morm/src
|
||||||
|
|
||||||
|
|
||||||
|
ezc:
|
||||||
|
$(MAKE) -C ../../../ezc/src
|
||||||
|
|
||||||
|
|
||||||
|
clean: FORCE
|
||||||
|
rm -f $(objfiles)
|
||||||
|
rm -f $(progname)
|
||||||
|
|
||||||
|
|
||||||
|
depend:
|
||||||
|
makedepend -w 10 -Y. -I../../../pikotools/src -I../../../morm/src -I../../../ezc/src -I../../../tito/src $(WINIX_NEEDED_MACROS) -f- $(sourcefiles) | sort -u > Makefile.dep
|
||||||
|
|
||||||
|
|
||||||
|
FORCE:
|
||||||
|
|
||||||
|
|
||||||
|
-include Makefile.dep
|
||||||
|
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
|
||||||
|
./main.o: ../../../ezc/src/blocks.h
|
||||||
|
./main.o: ../../../ezc/src/cache.h
|
||||||
|
./main.o: ../../../ezc/src/expressionparser.h
|
||||||
|
./main.o: ../../../ezc/src/ezc.h
|
||||||
|
./main.o: ../../../ezc/src/functions.h
|
||||||
|
./main.o: ../../../ezc/src/funinfo.h
|
||||||
|
./main.o: ../../../ezc/src/generator.h
|
||||||
|
./main.o: ../../../ezc/src/item.h
|
||||||
|
./main.o: ../../../ezc/src/models.h
|
||||||
|
./main.o: ../../../ezc/src/objects.h
|
||||||
|
./main.o: ../../../ezc/src/outstreams.h
|
||||||
|
./main.o: ../../../ezc/src/pattern.h
|
||||||
|
./main.o: ../../../ezc/src/patternparser.h
|
||||||
|
./main.o: ../../../ezc/src/version.h
|
||||||
|
./main.o: ../../../morm/src/baseexpression.h
|
||||||
|
./main.o: ../../../morm/src/baseobjectwrapper.h
|
||||||
|
./main.o: ../../../morm/src/clearer.h
|
||||||
|
./main.o: ../../../morm/src/cursorhelper.h
|
||||||
|
./main.o: ../../../morm/src/dbconnector.h
|
||||||
|
./main.o: ../../../morm/src/dbexpression.h
|
||||||
|
./main.o: ../../../morm/src/export.h
|
||||||
|
./main.o: ../../../morm/src/fieldvaluehelper.h
|
||||||
|
./main.o: ../../../morm/src/finderhelper.h
|
||||||
|
./main.o: ../../../morm/src/flatconnector.h
|
||||||
|
./main.o: ../../../morm/src/flatexpression.h
|
||||||
|
./main.o: ../../../morm/src/ft.h
|
||||||
|
./main.o: ../../../morm/src/model.h
|
||||||
|
./main.o: ../../../morm/src/modelconnector.h
|
||||||
|
./main.o: ../../../morm/src/modelcontainerwrapper.h
|
||||||
|
./main.o: ../../../morm/src/modeldata.h
|
||||||
|
./main.o: ../../../morm/src/modelenv.h
|
||||||
|
./main.o: ../../../morm/src/morm_types.h
|
||||||
|
./main.o: ../../../morm/src/queryresult.h
|
||||||
|
./main.o: ../../../morm/src/select.h
|
||||||
|
./main.o: ../../../morm/src/spacewrapper.h
|
||||||
|
./main.o: ../../../morm/src/wrapper.h
|
||||||
|
./main.o: ../../../pikotools/src/convert/inttostr.h
|
||||||
|
./main.o: ../../../pikotools/src/convert/misc.h
|
||||||
|
./main.o: ../../../pikotools/src/convert/strtoint.h
|
||||||
|
./main.o: ../../../pikotools/src/convert/text.h
|
||||||
|
./main.o: ../../../pikotools/src/date/date.h
|
||||||
|
./main.o: ../../../pikotools/src/log/filelog.h
|
||||||
|
./main.o: ../../../pikotools/src/log/log.h
|
||||||
|
./main.o: ../../../pikotools/src/mainoptions/mainoptionsparser.h
|
||||||
|
./main.o: ../../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./main.o: ../../../pikotools/src/space/space.h
|
||||||
|
./main.o: ../../../pikotools/src/textstream/stream_private.h
|
||||||
|
./main.o: ../../../pikotools/src/textstream/stream.h
|
||||||
|
./main.o: ../../../pikotools/src/textstream/textstream.h
|
||||||
|
./main.o: ../../../pikotools/src/textstream/types.h
|
||||||
|
./main.o: ../../../pikotools/src/utf8/utf8.h
|
||||||
|
./main.o: misc.h
|
||||||
|
./main.o: pgmodeler.h
|
||||||
|
./misc.o: ../../../pikotools/src/convert/inttostr.h
|
||||||
|
./misc.o: ../../../pikotools/src/convert/misc.h
|
||||||
|
./misc.o: ../../../pikotools/src/space/space.h
|
||||||
|
./misc.o: ../../../pikotools/src/textstream/stream.h
|
||||||
|
./misc.o: ../../../pikotools/src/utf8/utf8.h
|
||||||
|
./misc.o: misc.h
|
||||||
|
./pgmodeler.o: ../../../pikotools/src/convert/baseparser.h
|
||||||
|
./pgmodeler.o: ../../../pikotools/src/convert/inttostr.h
|
||||||
|
./pgmodeler.o: ../../../pikotools/src/convert/misc.h
|
||||||
|
./pgmodeler.o: ../../../pikotools/src/date/date.h
|
||||||
|
./pgmodeler.o: ../../../pikotools/src/html/htmlparser.h
|
||||||
|
./pgmodeler.o: ../../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./pgmodeler.o: ../../../pikotools/src/space/space.h
|
||||||
|
./pgmodeler.o: ../../../pikotools/src/textstream/stream_private.h
|
||||||
|
./pgmodeler.o: ../../../pikotools/src/textstream/stream.h
|
||||||
|
./pgmodeler.o: ../../../pikotools/src/textstream/textstream.h
|
||||||
|
./pgmodeler.o: ../../../pikotools/src/textstream/types.h
|
||||||
|
./pgmodeler.o: ../../../pikotools/src/utf8/utf8.h
|
||||||
|
./pgmodeler.o: misc.h
|
||||||
|
./pgmodeler.o: pgmodeler.h
|
||||||
|
# DO NOT DELETE
|
||||||
@@ -0,0 +1,295 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "convert/strtoint.h"
|
||||||
|
#include "mainoptions/mainoptionsparser.h"
|
||||||
|
#include "pgmodeler.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "ezc.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// make a static method in MainOptionsParser?
|
||||||
|
std::wstring get_param(const pt::Space::TableType * input_mode)
|
||||||
|
{
|
||||||
|
if( input_mode && input_mode->size() > 0 )
|
||||||
|
{
|
||||||
|
pt::Space * first_par = (*input_mode)[0];
|
||||||
|
|
||||||
|
if( first_par->is_table() && first_par->table_size() > 0 )
|
||||||
|
{
|
||||||
|
return first_par->value.value_table.front()->to_wstr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::wstring();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool use_pgmodeler(const std::wstring & input_file, const pt::Space & input_options, pt::Space & schema, bool sort_tables)
|
||||||
|
{
|
||||||
|
PGModeler pgmodeler;
|
||||||
|
return pgmodeler.parse(input_file, schema, sort_tables);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef pt::WTextStream MyStream;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// move me to a better place
|
||||||
|
void esc_tex(wchar_t c, pt::WTextStream & str)
|
||||||
|
{
|
||||||
|
if( c == '$' )
|
||||||
|
str << L"\\$";
|
||||||
|
else
|
||||||
|
if( c == '#' )
|
||||||
|
str << L"\\#";
|
||||||
|
else
|
||||||
|
if( c == '%' )
|
||||||
|
str << L"\\%";
|
||||||
|
else
|
||||||
|
if( c == '&' )
|
||||||
|
str << L"\\&";
|
||||||
|
else
|
||||||
|
if( c == '\\' )
|
||||||
|
str << L"$\\backslash$";
|
||||||
|
else
|
||||||
|
if( c == '{' )
|
||||||
|
str << L"$\\{$";
|
||||||
|
else
|
||||||
|
if( c == '}' )
|
||||||
|
str << L"$\\}$";
|
||||||
|
else
|
||||||
|
if( c == '^' )
|
||||||
|
str << L""; // !! IMPROVE ME add \char with specific code
|
||||||
|
else
|
||||||
|
if( c == '_' )
|
||||||
|
str << L"\\_";
|
||||||
|
else
|
||||||
|
if( c == '~' )
|
||||||
|
str << L""; // !! IMPROVE ME add \char with specific code
|
||||||
|
else
|
||||||
|
if( c == '-' )
|
||||||
|
str << L"{-}";
|
||||||
|
else
|
||||||
|
if( c != 0 )
|
||||||
|
str << c;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void fil_tex(Ezc::FunInfo<MyStream> & env)
|
||||||
|
{
|
||||||
|
auto i = env.in.begin();
|
||||||
|
|
||||||
|
for( ; i != env.in.end() ; ++i)
|
||||||
|
{
|
||||||
|
esc_tex(*i, env.out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void fil_max_size(Ezc::FunInfo<MyStream> & env)
|
||||||
|
{
|
||||||
|
auto i = env.in.begin();
|
||||||
|
size_t max_len = pt::to_ul(env.par);
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
for( ; i != env.in.end() ; ++i)
|
||||||
|
{
|
||||||
|
if( len >= max_len )
|
||||||
|
{
|
||||||
|
env.out << ' ';
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pt::is_white(*i) )
|
||||||
|
{
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
env.out << *i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cmp(Ezc::FunInfo<MyStream> & env)
|
||||||
|
{
|
||||||
|
if( env.params.size() >= 2 )
|
||||||
|
{
|
||||||
|
env.res = true;
|
||||||
|
|
||||||
|
for(size_t a=0 ; a < env.params.size() - 1 ; ++a)
|
||||||
|
{
|
||||||
|
if( env.params[a].str != env.params[a+1].str )
|
||||||
|
{
|
||||||
|
env.res = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool generate(const pt::Space & input_options, pt::Space & schema)
|
||||||
|
{
|
||||||
|
pt::WTextStream log_buffer;
|
||||||
|
pt::FileLog file_log;
|
||||||
|
pt::Log log;
|
||||||
|
|
||||||
|
file_log.init(L"log.txt", true, 4, true);
|
||||||
|
log.set_file_log(&file_log);
|
||||||
|
log.set_log_buffer(&log_buffer);
|
||||||
|
|
||||||
|
Ezc::Pattern pattern;
|
||||||
|
Ezc::PatternParser parser;
|
||||||
|
Ezc::Functions<MyStream> functions;
|
||||||
|
Ezc::Blocks blocks;
|
||||||
|
Ezc::Models models;
|
||||||
|
|
||||||
|
std::wstring dir = get_param(input_options.get_table(L"templates-dir"));
|
||||||
|
std::wstring template_file = get_param(input_options.get_table(L"template"));
|
||||||
|
|
||||||
|
if( dir.empty() )
|
||||||
|
{
|
||||||
|
std::cerr << "you have to set the templates directory with --templates-dir parameter" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( template_file.empty() )
|
||||||
|
{
|
||||||
|
std::cerr << "you have to set the template file name with --template_file parameter" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
functions.Insert("fil_tex", fil_tex);
|
||||||
|
functions.Insert("cmp", cmp);
|
||||||
|
functions.Insert("fil_max_size", fil_max_size);
|
||||||
|
|
||||||
|
parser.Directory(dir);
|
||||||
|
parser.SetBlocks(blocks);
|
||||||
|
parser.SetLogger(&log);
|
||||||
|
parser.ParseFile(template_file, pattern);
|
||||||
|
|
||||||
|
models.Add(L"schema", schema);
|
||||||
|
|
||||||
|
Ezc::Generator<MyStream, true, false> generator;
|
||||||
|
|
||||||
|
generator.SetPattern(pattern);
|
||||||
|
generator.SetFunctions(functions);
|
||||||
|
generator.SetModels(models);
|
||||||
|
|
||||||
|
MyStream str;
|
||||||
|
generator.SetLogger(log);
|
||||||
|
generator.Generate(str);
|
||||||
|
|
||||||
|
std::string tmp;
|
||||||
|
str.to_str(tmp);
|
||||||
|
std::cout << tmp << std::endl;
|
||||||
|
|
||||||
|
log << pt::Log::logsave;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, const char ** argv)
|
||||||
|
{
|
||||||
|
using namespace Winix;
|
||||||
|
|
||||||
|
pt::MainOptionsParser parser;
|
||||||
|
pt::Space input_options, args, schema;
|
||||||
|
|
||||||
|
args.add(L"input-mode", 1);
|
||||||
|
args.add(L"input-file", 1);
|
||||||
|
args.add(L"templates-dir", 1);
|
||||||
|
args.add(L"template", 1);
|
||||||
|
|
||||||
|
pt::MainOptionsParser::Status status = parser.parse(argc, argv, input_options, args);
|
||||||
|
|
||||||
|
std::wstring input_mode = get_param(input_options.get_table(L"input-mode"));
|
||||||
|
std::wstring input_file = get_param(input_options.get_table(L"input-file"));
|
||||||
|
|
||||||
|
if( input_mode.empty() )
|
||||||
|
{
|
||||||
|
std::cout << "you have to use --input-mode parameter" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
print("input-mode", input_mode);
|
||||||
|
print("input-file", input_file);
|
||||||
|
|
||||||
|
bool sort_tables = input_options.has_key(L"sort-tables");
|
||||||
|
|
||||||
|
if( input_mode == L"pgmodeler" )
|
||||||
|
{
|
||||||
|
if( !use_pgmodeler(input_file, input_options, schema, sort_tables) )
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "unknown --input-mode parameter, available are: pgmodeler" << std::endl;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
generate(input_options, schema);
|
||||||
|
|
||||||
|
|
||||||
|
// for debug purposes
|
||||||
|
// std::string tmp;
|
||||||
|
// tmp = input_options.serialize_to_json_str(true);
|
||||||
|
// std::cout << tmp << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
void print_nonl(const char * msg, const std::wstring & str)
|
||||||
|
{
|
||||||
|
std::string str_utf8;
|
||||||
|
pt::wide_to_utf8(str, str_utf8);
|
||||||
|
std::cerr << msg << ": " << str_utf8;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print(const char * msg, const std::wstring & str)
|
||||||
|
{
|
||||||
|
print_nonl(msg, str);
|
||||||
|
std::cerr << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print(const char * msg, const std::wstring & str, int val)
|
||||||
|
{
|
||||||
|
print_nonl(msg, str);
|
||||||
|
std::cerr << ":" << val << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winixcli_src_misc
|
||||||
|
#define headerfile_winixcli_src_misc
|
||||||
|
|
||||||
|
#include "space/space.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
void print_nonl(const char * msg, const std::wstring & str);
|
||||||
|
void print(const char * msg, const std::wstring & str);
|
||||||
|
void print(const char * msg, const std::wstring & str, int val);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pgmodeler.h"
|
||||||
|
#include "html/htmlparser.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
PGModeler::PGModeler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PGModeler::~PGModeler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool PGModeler::parse(const std::wstring & input_file, pt::Space & schema, bool sort_tables)
|
||||||
|
{
|
||||||
|
schema.clear();
|
||||||
|
pt::HTMLParser parser;
|
||||||
|
|
||||||
|
pt::HTMLParser::Status status = parser.parse_xml_file(input_file, schema, true, true);
|
||||||
|
|
||||||
|
if( status == pt::HTMLParser::Status::cant_open_file )
|
||||||
|
{
|
||||||
|
print("cannot open the input file", input_file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( status == pt::HTMLParser::Status::syntax_error )
|
||||||
|
{
|
||||||
|
print("syntax error", input_file, parser.get_last_parsed_line());
|
||||||
|
schema.clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( sort_tables )
|
||||||
|
make_sort_tables(schema);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::pair<const std::wstring*, const std::wstring*> PGModeler::get_schema_table_names(const pt::Space & table)
|
||||||
|
{
|
||||||
|
const pt::Space * schema = table.get_space(L"schema");
|
||||||
|
const std::wstring * schema_name = nullptr;
|
||||||
|
const std::wstring * table_name = nullptr;
|
||||||
|
|
||||||
|
if( schema )
|
||||||
|
{
|
||||||
|
const pt::Space * attr = schema->get_space(L"attr");
|
||||||
|
|
||||||
|
if( attr )
|
||||||
|
{
|
||||||
|
schema_name = attr->get_wstr(L"name");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const pt::Space * attr = table.get_space(L"attr");
|
||||||
|
|
||||||
|
if( attr )
|
||||||
|
{
|
||||||
|
table_name = attr->get_wstr(L"name");
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair(schema_name, table_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PGModeler::make_sort_tables(pt::Space & schema)
|
||||||
|
{
|
||||||
|
pt::Space * dbmodel = schema.get_space(L"dbmodel");
|
||||||
|
|
||||||
|
if( dbmodel )
|
||||||
|
{
|
||||||
|
pt::Space::TableType * table = dbmodel->get_table(L"table");
|
||||||
|
|
||||||
|
if( table )
|
||||||
|
{
|
||||||
|
std::sort(table->begin(), table->end(), [](const pt::Space * t1, const pt::Space * t2) -> bool {
|
||||||
|
auto t1_names = get_schema_table_names(*t1);
|
||||||
|
auto t2_names = get_schema_table_names(*t2);
|
||||||
|
|
||||||
|
if( t1_names.first && t2_names.second && t2_names.first && t2_names.second )
|
||||||
|
{
|
||||||
|
if( *t1_names.first != *t2_names.first )
|
||||||
|
{
|
||||||
|
return *t1_names.first < *t2_names.first;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return *t1_names.second < *t2_names.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winixcli_src_pgmodeler
|
||||||
|
#define headerfile_winixcli_src_pgmodeler
|
||||||
|
|
||||||
|
#include "space/space.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class PGModeler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
PGModeler();
|
||||||
|
~PGModeler();
|
||||||
|
|
||||||
|
bool parse(const std::wstring & input_file, pt::Space & schema, bool sort_tables);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void make_sort_tables(pt::Space & schema);
|
||||||
|
static std::pair<const std::wstring *, const std::wstring *> get_schema_table_names(const pt::Space & table);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+180
@@ -0,0 +1,180 @@
|
|||||||
|
# GNU Makefile
|
||||||
|
|
||||||
|
# sourcefiles: all *.cpp files except ./plugins subdirectory
|
||||||
|
# objfiles: corresponding *.o files
|
||||||
|
sourcefiles:=$(shell find . -name "*.cpp" -not \( -path ./plugins/\* \))
|
||||||
|
objfiles:=$(patsubst %.cpp,%.o,$(sourcefiles))
|
||||||
|
|
||||||
|
# sourcefiles_no_main: all *.cpp files except ./plugins and ./main subdirectories
|
||||||
|
sourcefiles_no_main:=$(shell find . -name "*.cpp" -not \( -path ./plugins/\* \) -not \( -path ./main/\* \))
|
||||||
|
objfiles_no_main:=$(patsubst %.cpp,%.o,$(sourcefiles_no_main))
|
||||||
|
|
||||||
|
# sourcefiles_main: all *.cpp files from ./main subdirectory
|
||||||
|
sourcefiles_main:=$(shell find main -name "*.cpp")
|
||||||
|
objfiles_main:=$(patsubst %.cpp,%.o,$(sourcefiles_main))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WINIX_PLUGINS_MAKEDEPEND_INCLUDES = -I../../../../winix/winixd \
|
||||||
|
-I../../../../pikotools/src \
|
||||||
|
-I../../../../morm/src \
|
||||||
|
-I../../../../ezc/src \
|
||||||
|
-I../../../../tito/src
|
||||||
|
|
||||||
|
WINIX_NEEDED_MACROS = -DPT_HAS_MORM_LIBRARY \
|
||||||
|
-DEZC_HAS_MORM_LIBRARY \
|
||||||
|
-DMORM_HAS_EZC_LIBRARY
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ifndef CXX
|
||||||
|
CXX = g++
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef CXXFLAGS
|
||||||
|
# /usr/include/postgresql is in Linux distros (Alpine)
|
||||||
|
CXXFLAGS = -Wall -pedantic -O2 -std=c++20 -fPIC -pthread \
|
||||||
|
-I/usr/local/include \
|
||||||
|
-I/usr/include/postgresql \
|
||||||
|
-I../../winix/winixd \
|
||||||
|
-I../../pikotools/src \
|
||||||
|
-I../../morm/src \
|
||||||
|
-I../../ezc/src \
|
||||||
|
-I../../tito/src \
|
||||||
|
$(WINIX_PLUGINS_MAKEDEPEND_INCLUDES) \
|
||||||
|
$(WINIX_NEEDED_MACROS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef LDFLAGS
|
||||||
|
LDFLAGS = -L/usr/local/lib -s
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
# for make install
|
||||||
|
ifndef WINIX_INSTALL_DIR
|
||||||
|
WINIX_INSTALL_DIR=/usr/local/winix
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(WINIX_INSTALL_DIR),)
|
||||||
|
$(error WINIX_INSTALL_DIR env variable cannot be empty)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
export CXX
|
||||||
|
export CXXFLAGS
|
||||||
|
export LDFLAGS
|
||||||
|
export WINIX_PLUGINS_MAKEDEPEND_INCLUDES
|
||||||
|
export WINIX_NEEDED_MACROS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
all: winix winix.so plugins
|
||||||
|
|
||||||
|
|
||||||
|
winix: $(objfiles_main) winix.so
|
||||||
|
$(CXX) -o winix $(CXXFLAGS) $(LDFLAGS) $(objfiles_main) winix.so -lcurl
|
||||||
|
|
||||||
|
|
||||||
|
winix.so: $(objfiles_no_main)
|
||||||
|
@cd ../../pikotools ; $(MAKE) -e
|
||||||
|
@cd ../../morm ; $(MAKE) -e
|
||||||
|
@cd ../../ezc ; $(MAKE) -e
|
||||||
|
@cd ../../tito ; $(MAKE) -e
|
||||||
|
$(CXX) -shared -rdynamic -Wl,-whole-archive -o winix.so $(CXXFLAGS) $(objfiles_no_main) ../../pikotools/src/pikotools.a ../../morm/src/morm.a ../../ezc/src/ezc.a ../../tito/src/tito.a $(LDFLAGS) -lfcgi -lpq -lz -lpthread -lmagic -Wl,-no-whole-archive
|
||||||
|
|
||||||
|
|
||||||
|
plugins: FORCE
|
||||||
|
@cd plugins/stats ; $(MAKE) -e
|
||||||
|
@cd plugins/thread ; $(MAKE) -e
|
||||||
|
@cd plugins/ticket ; $(MAKE) -e
|
||||||
|
@cd plugins/gallery ; $(MAKE) -e
|
||||||
|
@cd plugins/group ; $(MAKE) -e
|
||||||
|
@cd plugins/menu ; $(MAKE) -e
|
||||||
|
@cd plugins/export ; $(MAKE) -e
|
||||||
|
@cd plugins/mailregister ; $(MAKE) -e
|
||||||
|
@cd plugins/seo ; $(MAKE) -e
|
||||||
|
|
||||||
|
|
||||||
|
%.o: %.cpp
|
||||||
|
$(CXX) -c $(CXXFLAGS) -o $@ $<
|
||||||
|
|
||||||
|
|
||||||
|
FORCE:
|
||||||
|
|
||||||
|
|
||||||
|
clean: FORCE
|
||||||
|
rm -f $(objfiles)
|
||||||
|
rm -f winix.so
|
||||||
|
rm -f winix
|
||||||
|
@cd plugins/stats ; $(MAKE) -e clean
|
||||||
|
@cd plugins/thread ; $(MAKE) -e clean
|
||||||
|
@cd plugins/ticket ; $(MAKE) -e clean
|
||||||
|
@cd plugins/gallery ; $(MAKE) -e clean
|
||||||
|
@cd plugins/group ; $(MAKE) -e clean
|
||||||
|
@cd plugins/menu ; $(MAKE) -e clean
|
||||||
|
@cd plugins/export ; $(MAKE) -e clean
|
||||||
|
@cd plugins/mailregister ; $(MAKE) -e clean
|
||||||
|
@cd plugins/seo ; $(MAKE) -e clean
|
||||||
|
|
||||||
|
|
||||||
|
cleanall: clean
|
||||||
|
@cd ../../pikotools ; $(MAKE) -e clean
|
||||||
|
@cd ../../morm ; $(MAKE) -e clean
|
||||||
|
@cd ../../ezc ; $(MAKE) -e clean
|
||||||
|
@cd ../../tito ; $(MAKE) -e clean
|
||||||
|
|
||||||
|
|
||||||
|
depend:
|
||||||
|
makedepend -w 10 -Y. -I../../pikotools/src -I../../morm/src -I../../ezc/src -I../../tito/src $(WINIX_NEEDED_MACROS) -f- $(sourcefiles) | sort -u > Makefile.dep
|
||||||
|
@cd plugins/stats ; $(MAKE) -e depend
|
||||||
|
@cd plugins/thread ; $(MAKE) -e depend
|
||||||
|
@cd plugins/ticket ; $(MAKE) -e depend
|
||||||
|
@cd plugins/gallery ; $(MAKE) -e depend
|
||||||
|
@cd plugins/group ; $(MAKE) -e depend
|
||||||
|
@cd plugins/menu ; $(MAKE) -e depend
|
||||||
|
@cd plugins/export ; $(MAKE) -e depend
|
||||||
|
@cd plugins/mailregister ; $(MAKE) -e depend
|
||||||
|
@cd plugins/seo ; $(MAKE) -e depend
|
||||||
|
@cd ../../pikotools ; $(MAKE) -e depend
|
||||||
|
@cd ../../morm ; $(MAKE) -e depend
|
||||||
|
@cd ../../ezc ; $(MAKE) -e depend
|
||||||
|
@cd ../../tito ; $(MAKE) -e depend
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
install: all
|
||||||
|
# installing the main binary
|
||||||
|
rm -Rf $(WINIX_INSTALL_DIR)/bin
|
||||||
|
mkdir -p $(WINIX_INSTALL_DIR)/bin
|
||||||
|
cp winix $(WINIX_INSTALL_DIR)/bin
|
||||||
|
# installing the winix.so library
|
||||||
|
rm -Rf $(WINIX_INSTALL_DIR)/lib
|
||||||
|
mkdir -p $(WINIX_INSTALL_DIR)/lib
|
||||||
|
cp winix.so $(WINIX_INSTALL_DIR)/lib
|
||||||
|
# etc configs
|
||||||
|
rm -Rf $(WINIX_INSTALL_DIR)/etc
|
||||||
|
mkdir -p $(WINIX_INSTALL_DIR)/etc
|
||||||
|
cp -rf etc/* $(WINIX_INSTALL_DIR)/etc/
|
||||||
|
# html templates
|
||||||
|
rm -Rf $(WINIX_INSTALL_DIR)/html
|
||||||
|
mkdir -p $(WINIX_INSTALL_DIR)/html
|
||||||
|
cp -rf html/* $(WINIX_INSTALL_DIR)/html/
|
||||||
|
# txt templates
|
||||||
|
rm -Rf $(WINIX_INSTALL_DIR)/txt
|
||||||
|
mkdir -p $(WINIX_INSTALL_DIR)/txt
|
||||||
|
cp -rf txt/* $(WINIX_INSTALL_DIR)/txt/
|
||||||
|
# locales
|
||||||
|
rm -Rf $(WINIX_INSTALL_DIR)/locale
|
||||||
|
mkdir -p $(WINIX_INSTALL_DIR)/locale
|
||||||
|
cp -rf locale/* $(WINIX_INSTALL_DIR)/locale/
|
||||||
|
# plugins
|
||||||
|
rm -Rf $(WINIX_INSTALL_DIR)/plugins
|
||||||
|
mkdir -p $(WINIX_INSTALL_DIR)/plugins
|
||||||
|
find plugins/ -name "*.so" | xargs -I foo cp foo $(WINIX_INSTALL_DIR)/plugins/
|
||||||
|
# removing privileges for others
|
||||||
|
find $(WINIX_INSTALL_DIR) -exec chmod o-r,o-x,o-w "{}" "+"
|
||||||
|
|
||||||
|
|
||||||
|
-include Makefile.dep
|
||||||
|
|
||||||
|
|
||||||
+18028
File diff suppressed because it is too large
Load Diff
+1815
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,233 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_app
|
||||||
|
#define headerfile_winix_core_app
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <ctime>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcgiapp.h>
|
||||||
|
|
||||||
|
#include "sessionmanager.h"
|
||||||
|
#include "functions/functions.h"
|
||||||
|
#include "templates/templates.h"
|
||||||
|
#include "compress.h"
|
||||||
|
#include "postparser.h"
|
||||||
|
#include "cookieparser.h"
|
||||||
|
#include "postmultiparser.h"
|
||||||
|
#include "utils/acceptencodingparser.h"
|
||||||
|
#include "winixrequest.h"
|
||||||
|
#include "log/log.h"
|
||||||
|
#include "filelog.h"
|
||||||
|
#include "models/winixmodelconnector.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class App
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
App();
|
||||||
|
|
||||||
|
bool InitFCGI();
|
||||||
|
bool DropPrivileges();
|
||||||
|
void InitLoggers();
|
||||||
|
Log & GetMainLog();
|
||||||
|
bool InitializePlugins();
|
||||||
|
bool Init();
|
||||||
|
bool InitializeRequestForFastCGI(Request & request);
|
||||||
|
void SetRequestDependency(Request & request);
|
||||||
|
void InitializeNewRequest(Request & request);
|
||||||
|
void PutRequestToJob();
|
||||||
|
void Start();
|
||||||
|
void Close();
|
||||||
|
void LogUserGroups();
|
||||||
|
bool Demonize();
|
||||||
|
void SetStopSignal();
|
||||||
|
bool WasStopSignal();
|
||||||
|
Synchro * GetSynchro();
|
||||||
|
void StartThreads();
|
||||||
|
void WaitForThreads();
|
||||||
|
|
||||||
|
// configuration read from a config file
|
||||||
|
Config config;
|
||||||
|
|
||||||
|
// pointers to the current request and a session
|
||||||
|
Cur cur;
|
||||||
|
|
||||||
|
// users sessions
|
||||||
|
SessionManager session_manager;
|
||||||
|
|
||||||
|
// an unique id for each request
|
||||||
|
size_t request_id;
|
||||||
|
|
||||||
|
// ...
|
||||||
|
System system;
|
||||||
|
|
||||||
|
// functions (ls, cat, emacs, ...)
|
||||||
|
Functions functions;
|
||||||
|
|
||||||
|
// false at the beginning
|
||||||
|
// !! IMPROVE ME moze to do loggera dac?
|
||||||
|
bool stdout_is_closed;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Templates templates;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
PostParser post_parser;
|
||||||
|
PostMultiParser post_multi_parser;
|
||||||
|
pt::SpaceParser space_parser;
|
||||||
|
|
||||||
|
CookieParser cookie_parser;
|
||||||
|
AcceptBaseParser accept_base_parser;
|
||||||
|
AcceptEncodingParser accept_encoding_parser;
|
||||||
|
Compress compress;
|
||||||
|
int fcgi_socket;
|
||||||
|
Synchro synchro;
|
||||||
|
pthread_t signal_thread;
|
||||||
|
std::string socket_to_send_on_exit;
|
||||||
|
pt::WTextStream post_log_tmp_buffer;
|
||||||
|
|
||||||
|
std::wstring http_header_name;
|
||||||
|
std::wstring http_header_value;
|
||||||
|
pt::WTextStream empty_response;
|
||||||
|
|
||||||
|
WinixModelConnector model_connector; // main thread model connector, each thread has its own connector
|
||||||
|
morm::JSONConnector json_connector;
|
||||||
|
morm::XMLConnector xml_connector;
|
||||||
|
morm::PostgreSQLConnector postgresql_connector;
|
||||||
|
|
||||||
|
// objects for main thread
|
||||||
|
WinixBase winix_base;
|
||||||
|
WinixModelDeprecated winix_model;
|
||||||
|
WinixSystem winix_system;
|
||||||
|
WinixRequest winix_request;
|
||||||
|
// ///////////////////////
|
||||||
|
|
||||||
|
Plugin plugin;
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
|
||||||
|
// log_buffer for the main thread
|
||||||
|
pt::WTextStream log_buffer;
|
||||||
|
|
||||||
|
// logger only for the main thread
|
||||||
|
Log log;
|
||||||
|
|
||||||
|
// file logger, one object for all Log objects
|
||||||
|
FileLog file_log;
|
||||||
|
|
||||||
|
bool AddSystemThreads();
|
||||||
|
|
||||||
|
bool InitFCGIChmodChownSocket(const char * sock);
|
||||||
|
bool DropPrivileges(char * user, char * group);
|
||||||
|
bool DropPrivileges(const char * user, uid_t uid, gid_t gid, bool additional_groups);
|
||||||
|
bool CheckAccessFromPlugins();
|
||||||
|
void MakeRenameMeToABetterName();
|
||||||
|
bool AddRootDir();
|
||||||
|
void ProcessRequestThrow();
|
||||||
|
void ProcessRequest();
|
||||||
|
void BaseUrlRedirect(int code, bool add_subdomain);
|
||||||
|
bool BaseUrlRedirect();
|
||||||
|
void CheckIfNeedSSLredirect();
|
||||||
|
void SetLocale();
|
||||||
|
void CheckPostRedirect();
|
||||||
|
void AddDefaultModels();
|
||||||
|
void SaveSessionsIfNeeded(); // !! IMPROVE ME wywalic do menagera sesji??
|
||||||
|
void LogAccess();
|
||||||
|
void ReadRequest();
|
||||||
|
void LogEnvironmentVariables();
|
||||||
|
void LogEnvironmentHTTPVariables();
|
||||||
|
void ParseAcceptHeader(const wchar_t * header_name, const std::wstring & env, std::vector<HeaderValue> & container, size_t max_len);
|
||||||
|
void ParseAcceptHeader();
|
||||||
|
void ParseAcceptLanguageHeader();
|
||||||
|
void SetEnv(const char * name, std::wstring & env);
|
||||||
|
void ReadEnvVariables();
|
||||||
|
void ReadEnvHTTPVariables();
|
||||||
|
bool SaveEnvHTTPVariable(const char * env);
|
||||||
|
void ReadInputPostToBuffer();
|
||||||
|
void ParsePostJson();
|
||||||
|
void ReadPostJson(bool copy_raw_post);
|
||||||
|
void ReadPostVars();
|
||||||
|
void CheckIE();
|
||||||
|
void CheckKonqueror();
|
||||||
|
void CheckHtmx();
|
||||||
|
bool IsRequestedFrame();
|
||||||
|
void SendHeaders();
|
||||||
|
void SendCookies();
|
||||||
|
void ClearAfterRequest();
|
||||||
|
void IncrementRequestId();
|
||||||
|
|
||||||
|
void LogUser(const char * msg, uid_t id);
|
||||||
|
void LogGroup(const char * msg, gid_t id, bool put_logend = true);
|
||||||
|
void LogUsers();
|
||||||
|
void LogEffectiveGroups(std::vector<gid_t> & tab);
|
||||||
|
void LogGroups();
|
||||||
|
|
||||||
|
static void * SpecialThreadForSignals(void*);
|
||||||
|
void SendEmptyFastCGIPacket();
|
||||||
|
|
||||||
|
void CreateStaticTree();
|
||||||
|
|
||||||
|
bool DoDatabaseMigration();
|
||||||
|
bool TryToMakeDatabaseMigration();
|
||||||
|
|
||||||
|
|
||||||
|
// !! IMPROVE ME
|
||||||
|
// !! move to the session manager?
|
||||||
|
time_t last_sessions_save;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,288 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include "basethread.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
BaseThread::BaseThread() : thread_signal(PTHREAD_COND_INITIALIZER)
|
||||||
|
{
|
||||||
|
synchro = nullptr;
|
||||||
|
thread_id = 0;
|
||||||
|
work_mode = 0;
|
||||||
|
wake_up_was_called = false;
|
||||||
|
main_model_connector = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BaseThread::~BaseThread()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BaseThread::set_main_log_buffer(pt::WTextStream * log_buffer)
|
||||||
|
{
|
||||||
|
main_log.set_log_buffer(log_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BaseThread::set_main_file_log(pt::FileLog * file_log)
|
||||||
|
{
|
||||||
|
main_log.set_file_log(file_log);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BaseThread::set_main_model_connector(morm::ModelConnector * main_model_connector)
|
||||||
|
{
|
||||||
|
this->main_model_connector = main_model_connector;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BaseThread::Mode(int mode)
|
||||||
|
{
|
||||||
|
work_mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pthread_t BaseThread::ThreadId()
|
||||||
|
{
|
||||||
|
return thread_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool BaseThread::Lock()
|
||||||
|
{
|
||||||
|
return synchro->Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BaseThread::Unlock()
|
||||||
|
{
|
||||||
|
synchro->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool BaseThread::IsExitSignal()
|
||||||
|
{
|
||||||
|
bool res = true;
|
||||||
|
|
||||||
|
if( Lock() )
|
||||||
|
{
|
||||||
|
res = synchro->was_stop_signal;
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool BaseThread::BaseInit()
|
||||||
|
{
|
||||||
|
bool init_status = false;
|
||||||
|
|
||||||
|
if( Lock() )
|
||||||
|
{
|
||||||
|
init_status = Init(); // your virtual method
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return init_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BaseThread::BaseUninit()
|
||||||
|
{
|
||||||
|
if( Lock() )
|
||||||
|
{
|
||||||
|
Uninit(); // your virtual method
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool BaseThread::BaseSignalReceived()
|
||||||
|
{
|
||||||
|
bool make_do = false;
|
||||||
|
|
||||||
|
wake_up_was_called = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
make_do = SignalReceived(); // your short-time virtual method (objects are locked)
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return make_do;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// this is called only if your SignalReceived() returned true
|
||||||
|
void BaseThread::BaseDo()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Do(); // your long-time virtual method (objects are *not* locked)
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// use it with Lock and Unlock
|
||||||
|
bool BaseThread::WaitForSignal()
|
||||||
|
{
|
||||||
|
if( synchro->was_stop_signal || wake_up_was_called )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return pthread_cond_wait(&thread_signal, &synchro->mutex) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// you should use this method with: synchro->Lock() and Unlock()
|
||||||
|
void BaseThread::WakeUpThread()
|
||||||
|
{
|
||||||
|
wake_up_was_called = true;
|
||||||
|
pthread_cond_signal(&thread_signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// use it with Lock and Unlock
|
||||||
|
// it breaks only if there was a stop signal or the time has expired
|
||||||
|
bool BaseThread::WaitForSignalSleep(time_t second)
|
||||||
|
{
|
||||||
|
timespec t;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if( synchro->was_stop_signal )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
t.tv_sec = time(0) + second;
|
||||||
|
t.tv_nsec = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
res = pthread_cond_timedwait(&thread_signal, &synchro->mutex, &t);
|
||||||
|
}
|
||||||
|
while( res == 0 && !synchro->was_stop_signal );
|
||||||
|
// above condition means there was a signal
|
||||||
|
// but it was not a stop signal so we should still wait
|
||||||
|
|
||||||
|
return res == 0 || res == ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BaseThread::WaitForThread()
|
||||||
|
{
|
||||||
|
pthread_join(thread_id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BaseThread::SignalLoop()
|
||||||
|
{
|
||||||
|
bool make_do;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if( Lock() )
|
||||||
|
{
|
||||||
|
make_do = false;
|
||||||
|
|
||||||
|
if( WaitForSignal() ) // automatically unlock, wait and lock again when signal comes
|
||||||
|
if( !synchro->was_stop_signal )
|
||||||
|
make_do = BaseSignalReceived(); // your short-time virtual method will be called (objects locked)
|
||||||
|
|
||||||
|
Unlock(); // unlocking from WaitForSignal()
|
||||||
|
|
||||||
|
if( make_do )
|
||||||
|
BaseDo(); // your long-time virtual method will be called (objects *not* locked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while( !IsExitSignal() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void * BaseThread::StartRoutine(void * this_object)
|
||||||
|
{
|
||||||
|
BaseThread * base = reinterpret_cast<BaseThread*>(this_object);
|
||||||
|
|
||||||
|
if( base->synchro )
|
||||||
|
{
|
||||||
|
if( base->BaseInit() )
|
||||||
|
{
|
||||||
|
if( base->work_mode == 0 )
|
||||||
|
base->SignalLoop();
|
||||||
|
else
|
||||||
|
base->Work();
|
||||||
|
|
||||||
|
base->BaseUninit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base->save_log();
|
||||||
|
pthread_exit(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool BaseThread::StartThread()
|
||||||
|
{
|
||||||
|
pthread_attr_t attr;
|
||||||
|
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||||
|
|
||||||
|
int res = pthread_create(&thread_id, &attr, StartRoutine, this);
|
||||||
|
|
||||||
|
pthread_attr_destroy(&attr);
|
||||||
|
|
||||||
|
return res == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_basethread
|
||||||
|
#define headerfile_winix_core_basethread
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include "synchro.h"
|
||||||
|
#include "winixmodeldeprecated.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class BaseThread : public WinixModelDeprecated
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
BaseThread();
|
||||||
|
virtual ~BaseThread();
|
||||||
|
|
||||||
|
void set_main_log_buffer(pt::WTextStream * log_buffer);
|
||||||
|
void set_main_file_log(pt::FileLog * file_log);
|
||||||
|
|
||||||
|
void set_main_model_connector(morm::ModelConnector * main_model_connector);
|
||||||
|
|
||||||
|
// work mode
|
||||||
|
// we have two modes:
|
||||||
|
// 0 - there is a loop with SignalReceived() and Do()
|
||||||
|
// if SignalReceived() returns true then Do() is called
|
||||||
|
// 1 - only Work() method is called
|
||||||
|
// the thread exits after Work() has finished
|
||||||
|
// default: 0
|
||||||
|
void Mode(int mode);
|
||||||
|
|
||||||
|
// starting the second thread
|
||||||
|
bool StartThread();
|
||||||
|
|
||||||
|
|
||||||
|
// virtual methods which should/can be inherited by your class
|
||||||
|
// the methods will be called from the other thread
|
||||||
|
|
||||||
|
// wake up the second thread
|
||||||
|
// (if it waits for the signal)
|
||||||
|
// you should use it with: synchro->Lock() and Unlock()
|
||||||
|
// if the thread doesn't wait on a signal then nothing is done
|
||||||
|
virtual void WakeUpThread();
|
||||||
|
|
||||||
|
// waiting until the thread exits
|
||||||
|
// you should call WakeUpThread() before
|
||||||
|
virtual void WaitForThread();
|
||||||
|
|
||||||
|
// initialize the thread
|
||||||
|
// (global objects are locked)
|
||||||
|
// if it returns false then the thread immediately exits
|
||||||
|
// default: true
|
||||||
|
virtual bool Init() { return true; }
|
||||||
|
|
||||||
|
// uninitialize the thread
|
||||||
|
// this is called before the thread is prepare to detach
|
||||||
|
// (global objects are locked)
|
||||||
|
// it's called only if Init() returned true
|
||||||
|
virtual void Uninit() {}
|
||||||
|
|
||||||
|
// returns the thread id
|
||||||
|
// this identifier is set by StartThread() metdhod
|
||||||
|
pthread_t ThreadId();
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// logger for the main thread
|
||||||
|
Log main_log;
|
||||||
|
// log from WinixBase is meant to be used by the second thread
|
||||||
|
|
||||||
|
// model connector for the main thread
|
||||||
|
// model_connector from the based class WinixModelDeprecated is meant to be used by the second thread
|
||||||
|
morm::ModelConnector * main_model_connector;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// signal came (work mode = 0 - default)
|
||||||
|
// signal comes when an other thread calls WakeUpThread() method
|
||||||
|
// check specific job and return true to call Do() next
|
||||||
|
// (global objects are locked -- copy some global objects to local variables)
|
||||||
|
virtual bool SignalReceived() { return false; };
|
||||||
|
|
||||||
|
// if SignalReceived() returned true then this method is called
|
||||||
|
// global objects are *not* locked -- use only your local variables
|
||||||
|
// if you have to do something on global objects use synchro->Lock() and synchro->Unlock()
|
||||||
|
virtual void Do() {}
|
||||||
|
|
||||||
|
// this method is called after Init() when Mode(1) is used
|
||||||
|
// this is for long-time job
|
||||||
|
// this method is called only once
|
||||||
|
// global objects are *not* locked
|
||||||
|
virtual void Work() {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
pthread_t thread_id; // thread id - set by StartThread()
|
||||||
|
pthread_cond_t thread_signal;
|
||||||
|
int work_mode;
|
||||||
|
bool wake_up_was_called;
|
||||||
|
|
||||||
|
void SignalLoop();
|
||||||
|
static void * StartRoutine(void *);
|
||||||
|
virtual bool BaseInit();
|
||||||
|
virtual void BaseUninit();
|
||||||
|
virtual bool BaseSignalReceived();
|
||||||
|
virtual void BaseDo();
|
||||||
|
virtual bool WaitForSignal();
|
||||||
|
virtual bool WaitForSignalSleep(time_t second);
|
||||||
|
|
||||||
|
bool Lock();
|
||||||
|
void Unlock();
|
||||||
|
|
||||||
|
// if the work done by Do() is long time consuming you should periodically check
|
||||||
|
// wheter there was a signal for exiting, and if it was just simply return from Do()
|
||||||
|
// (it's checking with locking and unlocking)
|
||||||
|
bool IsExitSignal();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,435 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2014, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "compress.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Compress::Compress()
|
||||||
|
{
|
||||||
|
buffer_in = 0;
|
||||||
|
buffer_out = 0;
|
||||||
|
buffer_max_len = 65536; // 64KB
|
||||||
|
ready_for_compress = false;
|
||||||
|
compress_level = 6;
|
||||||
|
raw_deflate_inited = false;
|
||||||
|
deflate_inited = false;
|
||||||
|
gzip_inited = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Compress::~Compress()
|
||||||
|
{
|
||||||
|
delete [] buffer_in;
|
||||||
|
delete [] buffer_out;
|
||||||
|
|
||||||
|
if( raw_deflate_inited )
|
||||||
|
deflateEnd(&strm_raw_deflate);
|
||||||
|
|
||||||
|
if( deflate_inited )
|
||||||
|
deflateEnd(&strm_deflate);
|
||||||
|
|
||||||
|
if( gzip_inited )
|
||||||
|
deflateEnd(&strm_gzip);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Compress::AllocateMemory()
|
||||||
|
{
|
||||||
|
if( buffer_in )
|
||||||
|
delete [] buffer_in;
|
||||||
|
|
||||||
|
if( buffer_out )
|
||||||
|
delete [] buffer_out;
|
||||||
|
|
||||||
|
buffer_in = 0;
|
||||||
|
buffer_out = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
buffer_in = new char[buffer_max_len];
|
||||||
|
buffer_out = new char[buffer_max_len];
|
||||||
|
}
|
||||||
|
catch(const std::bad_alloc &)
|
||||||
|
{
|
||||||
|
log << log1 << "Compress: can't allocate memory" << logend;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Compress::InitRawDeflate()
|
||||||
|
{
|
||||||
|
raw_deflate_inited = false;
|
||||||
|
|
||||||
|
strm_raw_deflate.next_in = 0;
|
||||||
|
strm_raw_deflate.zalloc = Z_NULL;
|
||||||
|
strm_raw_deflate.zfree = Z_NULL;
|
||||||
|
strm_raw_deflate.opaque = Z_NULL;
|
||||||
|
|
||||||
|
int ret = deflateInit2(&strm_raw_deflate, compress_level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
|
||||||
|
|
||||||
|
if( ret != Z_OK )
|
||||||
|
log << log1 << "Compress: problem with deflateInit2() for raw deflate" << logend;
|
||||||
|
else
|
||||||
|
raw_deflate_inited = true;
|
||||||
|
|
||||||
|
return ret == Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Compress::InitDeflate()
|
||||||
|
{
|
||||||
|
deflate_inited = false;
|
||||||
|
|
||||||
|
strm_deflate.next_in = 0;
|
||||||
|
strm_deflate.zalloc = Z_NULL;
|
||||||
|
strm_deflate.zfree = Z_NULL;
|
||||||
|
strm_deflate.opaque = Z_NULL;
|
||||||
|
|
||||||
|
int ret = deflateInit2(&strm_deflate, compress_level, Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY);
|
||||||
|
|
||||||
|
if( ret != Z_OK )
|
||||||
|
log << log1 << "Compress: problem with deflateInit2() for deflate" << logend;
|
||||||
|
else
|
||||||
|
deflate_inited = true;
|
||||||
|
|
||||||
|
return ret == Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Compress::InitGzip()
|
||||||
|
{
|
||||||
|
gzip_inited = false;
|
||||||
|
|
||||||
|
strm_gzip.next_in = 0;
|
||||||
|
strm_gzip.zalloc = Z_NULL;
|
||||||
|
strm_gzip.zfree = Z_NULL;
|
||||||
|
strm_gzip.opaque = Z_NULL;
|
||||||
|
|
||||||
|
int ret = deflateInit2(&strm_gzip, compress_level, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY);
|
||||||
|
|
||||||
|
if( ret != Z_OK )
|
||||||
|
log << log1 << "Compress: problem with deflateInit2() for gzip" << logend;
|
||||||
|
else
|
||||||
|
gzip_inited = true;
|
||||||
|
|
||||||
|
return ret == Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
return:
|
||||||
|
0 - ok
|
||||||
|
1 - can't allocate memory
|
||||||
|
100 - unknown error
|
||||||
|
*/
|
||||||
|
int Compress::Init(int compress_level_)
|
||||||
|
{
|
||||||
|
compress_level = compress_level_;
|
||||||
|
|
||||||
|
if( !AllocateMemory() )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if( InitRawDeflate() && InitDeflate() && InitGzip() )
|
||||||
|
ready_for_compress = true;
|
||||||
|
else
|
||||||
|
return 100;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int Compress::MakeCompress(z_stream & strm, const char * source, size_t source_len, BinaryPage & out_stream, int encoding)
|
||||||
|
{
|
||||||
|
int ret, flush;
|
||||||
|
size_t have;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
strm.avail_in = (source_len > buffer_max_len) ? buffer_max_len : source_len;
|
||||||
|
source_len -= strm.avail_in;
|
||||||
|
flush = (source_len == 0) ? Z_FINISH : Z_NO_FLUSH;
|
||||||
|
strm.next_in = (Bytef*)source;
|
||||||
|
source += strm.avail_in;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
strm.avail_out = buffer_max_len;
|
||||||
|
strm.next_out = (Bytef*)buffer_out;
|
||||||
|
ret = deflate(&strm, flush);
|
||||||
|
|
||||||
|
if( ret == Z_STREAM_ERROR || ret == Z_BUF_ERROR )
|
||||||
|
{
|
||||||
|
log << log1 << "Compress: problem with deflate()" << logend;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
have = buffer_max_len - strm.avail_out;
|
||||||
|
last_out_size += have;
|
||||||
|
out_stream.write(buffer_out, have);
|
||||||
|
}
|
||||||
|
while( strm.avail_out == 0 );
|
||||||
|
|
||||||
|
if( strm.avail_in != 0 )
|
||||||
|
{
|
||||||
|
log << log1 << "Compress: problem with deflate() - not all input is used" << logend;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while( flush != Z_FINISH );
|
||||||
|
|
||||||
|
|
||||||
|
if( ret != Z_STREAM_END )
|
||||||
|
{
|
||||||
|
log << log1 << "Compress: problem with deflate() - stream not complete" << logend;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Compress::CopyToInputBuffer(BinaryPage::const_iterator & i, size_t len)
|
||||||
|
{
|
||||||
|
for(size_t a=0 ; a<len ; ++a, ++i)
|
||||||
|
buffer_in[a] = *i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// new way
|
||||||
|
int Compress::MakeCompress(z_stream & strm, const BinaryPage & page, BinaryPage & out, int encoding)
|
||||||
|
{
|
||||||
|
int ret, flush;
|
||||||
|
size_t have;
|
||||||
|
BinaryPage::const_iterator i = page.begin();
|
||||||
|
|
||||||
|
size_t source_len = page.size();
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
strm.avail_in = (source_len > buffer_max_len) ? buffer_max_len : source_len;
|
||||||
|
source_len -= strm.avail_in;
|
||||||
|
flush = (source_len == 0) ? Z_FINISH : Z_NO_FLUSH;
|
||||||
|
strm.next_in = (Bytef*)buffer_in;
|
||||||
|
|
||||||
|
// IMPROVE ME we can add an interface to pt::TextStreamBase<> and get all chunks of memory
|
||||||
|
CopyToInputBuffer(i, strm.avail_in);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
strm.avail_out = buffer_max_len;
|
||||||
|
strm.next_out = (Bytef*)buffer_out;
|
||||||
|
ret = deflate(&strm, flush);
|
||||||
|
|
||||||
|
if( ret == Z_STREAM_ERROR || ret == Z_BUF_ERROR )
|
||||||
|
{
|
||||||
|
log << log1 << "Compress: problem with deflate()" << logend;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
have = buffer_max_len - strm.avail_out;
|
||||||
|
last_out_size += have;
|
||||||
|
out.write(buffer_out, have);
|
||||||
|
}
|
||||||
|
while( strm.avail_out == 0 );
|
||||||
|
|
||||||
|
if( strm.avail_in != 0 )
|
||||||
|
{
|
||||||
|
log << log1 << "Compress: problem with deflate() - not all input is used" << logend;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while( flush != Z_FINISH );
|
||||||
|
|
||||||
|
|
||||||
|
if( ret != Z_STREAM_END )
|
||||||
|
{
|
||||||
|
log << log1 << "Compress: problem with deflate() - stream not complete" << logend;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
z_stream * Compress::SelectStream(int encoding)
|
||||||
|
{
|
||||||
|
z_stream * pstrm;
|
||||||
|
|
||||||
|
if( encoding == 0 )
|
||||||
|
pstrm = &strm_raw_deflate;
|
||||||
|
else
|
||||||
|
if( encoding == 1 )
|
||||||
|
pstrm = &strm_deflate;
|
||||||
|
else
|
||||||
|
pstrm = &strm_gzip;
|
||||||
|
|
||||||
|
return pstrm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Compress::ResetStream(z_stream * pstrm, int encoding)
|
||||||
|
{
|
||||||
|
if( deflateReset(pstrm) != Z_OK )
|
||||||
|
{
|
||||||
|
log << log1 << "Compress: problem with deflateReset()" << logend;
|
||||||
|
|
||||||
|
deflateEnd(pstrm);
|
||||||
|
|
||||||
|
if( encoding == 0 )
|
||||||
|
InitRawDeflate();
|
||||||
|
else
|
||||||
|
if( encoding == 1 )
|
||||||
|
InitDeflate();
|
||||||
|
else
|
||||||
|
InitGzip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Compress::PutLog(size_t source_len, int encoding)
|
||||||
|
{
|
||||||
|
double ratio = 100.0 - (double(last_out_size) / double(source_len) * 100.0);
|
||||||
|
char buffer[30];
|
||||||
|
sprintf(buffer, "%.1f", ratio);
|
||||||
|
|
||||||
|
log << log2 << "Compress: ";
|
||||||
|
|
||||||
|
if( encoding == 0 )
|
||||||
|
log << "raw deflate";
|
||||||
|
else
|
||||||
|
if( encoding == 1 )
|
||||||
|
log << "deflate";
|
||||||
|
else
|
||||||
|
log << "gzip";
|
||||||
|
|
||||||
|
log << ", original size: " << source_len << ", size after compressing: "
|
||||||
|
<< (int)last_out_size << ", ratio: " << buffer << "%" << logend;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
return:
|
||||||
|
0 - ok;
|
||||||
|
1 - can't allocate memory
|
||||||
|
2 - error during compressing
|
||||||
|
3 - not inited (use Init() first)
|
||||||
|
100 - unknown
|
||||||
|
*/
|
||||||
|
int Compress::Compressing(const char * source, size_t source_len, BinaryPage & out_stream, int encoding)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
z_stream * pstrm;
|
||||||
|
|
||||||
|
last_out_size = 0;
|
||||||
|
out_stream.clear();
|
||||||
|
|
||||||
|
if( !ready_for_compress )
|
||||||
|
{
|
||||||
|
log << log1 << "Compress: not ready yet" << logend;
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// !! CHECK ME
|
||||||
|
// it is correct to immediately return? what about headers in the compressed page?
|
||||||
|
if( source_len == 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pstrm = SelectStream(encoding);
|
||||||
|
ret = MakeCompress(*pstrm, source, source_len, out_stream, encoding);
|
||||||
|
ResetStream(pstrm, encoding);
|
||||||
|
PutLog(source_len, encoding);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
return:
|
||||||
|
0 - ok;
|
||||||
|
1 - can't allocate memory
|
||||||
|
2 - error during compressing
|
||||||
|
3 - not inited (use Init() first)
|
||||||
|
100 - unknown
|
||||||
|
*/
|
||||||
|
int Compress::Compressing(const BinaryPage & in, BinaryPage & out, int encoding)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
z_stream * pstrm;
|
||||||
|
|
||||||
|
last_out_size = 0;
|
||||||
|
out.clear();
|
||||||
|
|
||||||
|
if( !ready_for_compress )
|
||||||
|
{
|
||||||
|
log << log1 << "Compress: not ready yet" << logend;
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// !! CHECK ME
|
||||||
|
// it is correct to immediately return? what about headers in the compressed page?
|
||||||
|
if( in.empty() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pstrm = SelectStream(encoding);
|
||||||
|
ret = MakeCompress(*pstrm, in, out, encoding);
|
||||||
|
ResetStream(pstrm, encoding);
|
||||||
|
PutLog(in.size(), encoding);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2014, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_compress
|
||||||
|
#define headerfile_winix_core_compress
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <zlib.h>
|
||||||
|
#include "requesttypes.h"
|
||||||
|
#include "winixbase.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Compress : public WinixBase
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Compress();
|
||||||
|
~Compress();
|
||||||
|
|
||||||
|
int Init(int compress_level_ = 6);
|
||||||
|
|
||||||
|
/*
|
||||||
|
encoding:
|
||||||
|
0 - raw deflate data with no zlib header or trailer, and will not compute an adler32 check value
|
||||||
|
(for Internet Explorer)
|
||||||
|
1 - deflate
|
||||||
|
2 - gzip
|
||||||
|
*/
|
||||||
|
int Compressing(const char * source, size_t source_len, BinaryPage & out_stream, int encoding = 2);
|
||||||
|
int Compressing(const BinaryPage & in, BinaryPage & out, int encoding = 2);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool AllocateMemory();
|
||||||
|
bool InitRawDeflate();
|
||||||
|
bool InitDeflate();
|
||||||
|
bool InitGzip();
|
||||||
|
|
||||||
|
int MakeCompress(z_stream & strm, const char * source, size_t source_len, BinaryPage & out_stream, int encoding);
|
||||||
|
int MakeCompress(z_stream & strm, const BinaryPage & page, BinaryPage & out, int encoding);
|
||||||
|
z_stream * SelectStream(int encoding);
|
||||||
|
void ResetStream(z_stream * pstrm, int encoding);
|
||||||
|
void PutLog(size_t source_len, int encoding);
|
||||||
|
void CopyToInputBuffer(BinaryPage::const_iterator & i, size_t len);
|
||||||
|
|
||||||
|
int compress_level;
|
||||||
|
size_t buffer_max_len;
|
||||||
|
|
||||||
|
// size of the last compressed page
|
||||||
|
size_t last_out_size;
|
||||||
|
|
||||||
|
char * buffer_in;
|
||||||
|
char * buffer_out;
|
||||||
|
z_stream strm_raw_deflate, strm_deflate, strm_gzip;
|
||||||
|
bool raw_deflate_inited, deflate_inited, gzip_inited;
|
||||||
|
bool ready_for_compress;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,553 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "crypt.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Config::Config()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Config::SetFileLog(FileLog * file_log)
|
||||||
|
{
|
||||||
|
log.set_file_log(file_log);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Config::SetLogBuffer(pt::WTextStream * log_buffer)
|
||||||
|
{
|
||||||
|
log.set_log_buffer(log_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Config::ShowError(const std::wstring & config_file)
|
||||||
|
{
|
||||||
|
switch( parser.status )
|
||||||
|
{
|
||||||
|
case pt::SpaceParser::ok:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case pt::SpaceParser::cant_open_file:
|
||||||
|
log << log1 << "Config: I cannot open a config file: " << config_file << logend;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case pt::SpaceParser::syntax_error:
|
||||||
|
log << log1 << "Config: syntax error in file: " << config_file << ", line: "
|
||||||
|
<< parser.get_last_parsed_line() << ":" << parser.get_last_parsed_column() << logend;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// there are no limits sets when parsing the config file
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Config::ReadConfig(const std::wstring & config_file)
|
||||||
|
{
|
||||||
|
if( config_file.empty() )
|
||||||
|
{
|
||||||
|
log << log2 << "Config: name of the config file is empty" << logend;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
log << log2 << "Config: reading a config file: " << config_file << logend;
|
||||||
|
pt::SpaceParser::Status status = parser.parse_space_file(config_file, space, false);
|
||||||
|
|
||||||
|
if( status == pt::SpaceParser::ok )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ShowError(config_file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Config::AssignValuesFromSpace()
|
||||||
|
{
|
||||||
|
AssignValues();
|
||||||
|
SetAdditionalVariables();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Config::AssignValues()
|
||||||
|
{
|
||||||
|
server_mode = Text(L"server_mode");
|
||||||
|
demonize = Bool(L"demonize", true);
|
||||||
|
|
||||||
|
user = Text(L"user");
|
||||||
|
group = Text(L"group");
|
||||||
|
additional_groups = Bool(L"additional_groups", true);
|
||||||
|
|
||||||
|
log_file = Text(L"log_file");
|
||||||
|
log_delimiter = Text(L"log_delimiter", L"---------------------------------------------------------------------------------");
|
||||||
|
fcgi_socket = Text(L"fcgi_socket");
|
||||||
|
fcgi_set_socket_chmod = Bool(L"fcgi_set_socket_chmod", true);
|
||||||
|
fcgi_set_socket_owner = Bool(L"fcgi_set_socket_owner", true);
|
||||||
|
fcgi_socket_chmod = Int(L"fcgi_socket_chmod", 0770);
|
||||||
|
fcgi_socket_user = Text(L"fcgi_socket_user");
|
||||||
|
fcgi_socket_group = Text(L"fcgi_socket_group");
|
||||||
|
fcgi_socket_listen = Int(L"fcgi_socket_listen", 1024);
|
||||||
|
fcgi_cannot_create_request_delay = Size(L"fcgi_cannot_create_request_delay", 3);
|
||||||
|
log_level = Int(L"log_level", 1);
|
||||||
|
log_request = Int(L"log_request", 1);
|
||||||
|
log_save_each_line = Bool(L"log_save_each_line", false);
|
||||||
|
log_time_zone_id = Size(L"log_time_zone_id", 34);
|
||||||
|
log_server_answer = Bool(L"log_server_answer", false);
|
||||||
|
log_stdout = Bool(L"log_stdout", false);
|
||||||
|
log_db_query = Bool(L"log_db_query", false);
|
||||||
|
log_plugin_call = Bool(L"log_plugin_call", false);
|
||||||
|
log_post_value_size = Size(L"log_post_value_size", 80);
|
||||||
|
log_env_variables = Bool(L"log_env_variables", false);
|
||||||
|
log_env_http_variables = Bool(L"log_env_http_variables", false);
|
||||||
|
log_whole_http_post = Bool(L"log_whole_http_post", false);
|
||||||
|
log_http_answer_headers = Bool(L"log_http_answer_headers", false);
|
||||||
|
|
||||||
|
post_file_max = Size(L"post_file_max", 8388608); // 8 MB
|
||||||
|
post_json_max = Size(L"post_json_max", 8388608); // 8 MB
|
||||||
|
post_max_object_items = Size(L"post_max_object_items", 1024);
|
||||||
|
post_max_table_items = Size(L"post_max_table_items", 4096);
|
||||||
|
post_max_all_items = Size(L"post_max_all_items", 8192);
|
||||||
|
post_max_nested_objects = Size(L"post_max_nested_objects", 32);
|
||||||
|
|
||||||
|
upload_dir = Text(L"upload_dir");
|
||||||
|
common_dir = Text(L"common_dir");
|
||||||
|
NoLastSlash(upload_dir);
|
||||||
|
NoLastSlash(common_dir);
|
||||||
|
|
||||||
|
upload_group = Text(L"upload_group");
|
||||||
|
upload_dirs_chmod = Int(L"upload_dirs_chmod", 0750);
|
||||||
|
upload_files_chmod = Int(L"upload_files_chmod", 0640);
|
||||||
|
ListText(L"static_dirs", static_dirs);
|
||||||
|
dont_use_static_dirs = Bool(L"dont_use_static_dirs", false);
|
||||||
|
create_thumb = Bool(L"create_thumb", true);
|
||||||
|
thumb_mode = Int(L"thumb_mode", 2);
|
||||||
|
thumb_cx = Size(L"thumb_cx", 150);
|
||||||
|
thumb_cy = Size(L"thumb_cy", 150);
|
||||||
|
thumb_quality = Int(L"thumb_quality", 92);
|
||||||
|
image_resize = Bool(L"image_resize", true);
|
||||||
|
image_mode = Int(L"image_mode", 6);
|
||||||
|
image_cx = Size(L"image_cx", 1000);
|
||||||
|
image_cy = Size(L"image_cy", 800);
|
||||||
|
image_quality = Int(L"image_quality", 92);
|
||||||
|
convert_cmd = Text(L"convert_cmd", L"/usr/local/bin/convert");
|
||||||
|
|
||||||
|
templates_dir = Text(L"templates_dir");
|
||||||
|
templates_dir_default = Text(L"templates_dir_default");
|
||||||
|
txt_templates_dir = Text(L"txt_templates_dir");
|
||||||
|
txt_templates_dir_default = Text(L"txt_templates_dir_default");
|
||||||
|
templates_fun_prefix = Text(L"templates_fun_prefix", L"fun_");
|
||||||
|
templates_fun_postfix = Text(L"templates_fun_postfix", L".html");
|
||||||
|
templates_index = Text(L"templates_index", L"index.html");
|
||||||
|
templates_index_generic = Text(L"templates_index_generic", L"index_generic.html");
|
||||||
|
templates_index_raw = Text(L"templates_index_raw", L"index_raw.html");
|
||||||
|
templates_request_status = Text(L"templates_request_status", L"request_status.html");
|
||||||
|
template_only_root_use_template_fun = Bool(L"template_only_root_use_template_fun", false);
|
||||||
|
|
||||||
|
use_internal_session_mechanism = Bool(L"use_internal_session_mechanism", true);
|
||||||
|
use_internal_loggin_mechanism = Bool(L"use_internal_loggin_mechanism", true);
|
||||||
|
|
||||||
|
session_cookie_name = Text(L"session_cookie_name", L"session_id");
|
||||||
|
session_cookie_path = Text(L"session_cookie_path", L"/");
|
||||||
|
session_cookie_domain = Text(L"session_cookie_domain", L"");
|
||||||
|
session_cookie_same_site = Int(L"session_cookie_same_site", 0);
|
||||||
|
session_cookie_http_only = Bool(L"session_cookie_http_only", false);
|
||||||
|
session_cookie_secure = Bool(L"session_cookie_secure", false);
|
||||||
|
|
||||||
|
db_conn_string = Text(L"db_conn_string");
|
||||||
|
db_host = Text(L"db_host");
|
||||||
|
db_hostaddr = Text(L"db_hostaddr");
|
||||||
|
db_port = Text(L"db_port");
|
||||||
|
db_database = Text(L"db_database");
|
||||||
|
db_user = Text(L"db_user");
|
||||||
|
db_pass = Text(L"db_pass");
|
||||||
|
db_startup_connection_max_attempts = Size(L"db_startup_connection_max_attempts", 0);
|
||||||
|
db_startup_connection_attempt_delay = Size(L"db_startup_connection_attempt_delay", 5);
|
||||||
|
db_make_migration_if_needed = Bool(L"db_make_migration_if_needed", true);
|
||||||
|
db_stop_if_migration_fails = Bool(L"db_stop_if_migration_fails", true);
|
||||||
|
|
||||||
|
|
||||||
|
item_url_empty = Text(L"item_url_empty");
|
||||||
|
|
||||||
|
url_proto = Text(L"url_proto", L"http://");
|
||||||
|
url_ssl_proto = Text(L"url_ssl_proto", L"https://");
|
||||||
|
|
||||||
|
use_ssl = Bool(L"use_ssl", false);
|
||||||
|
use_ssl_static = Bool(L"use_ssl_static", false);
|
||||||
|
use_ssl_common = Bool(L"use_ssl_common", false);
|
||||||
|
use_ssl_only_for_logged_users = Bool(L"use_ssl_only_for_logged_users", false);
|
||||||
|
use_ssl_redirect_code = Int(L"use_ssl_redirect_code", 303);
|
||||||
|
assume_connection_is_through_ssl = Bool(L"assume_connection_is_through_ssl", false);
|
||||||
|
|
||||||
|
base_url = Text(L"base_url");
|
||||||
|
base_url_static = Text(L"base_url_static");
|
||||||
|
base_url_common = Text(L"base_url_common");
|
||||||
|
|
||||||
|
base_url_redirect = Bool(L"base_url_redirect", false);
|
||||||
|
base_url_redirect_code = Int(L"base_url_redirect_code", 301);
|
||||||
|
|
||||||
|
NoLastSlash(base_url);
|
||||||
|
NoLastSlash(base_url_static);
|
||||||
|
NoLastSlash(base_url_common);
|
||||||
|
|
||||||
|
priv_no_user = Text(L"priv_no_user", L"-- no user --");
|
||||||
|
priv_no_group = Text(L"priv_no_group", L"-- no group --");
|
||||||
|
|
||||||
|
session_max_idle = Int(L"session_max_idle", 10800); // 3h
|
||||||
|
session_remember_max_idle = Int(L"session_remember_max_idle", 16070400); // 3 months
|
||||||
|
session_file = Text(L"session_file");
|
||||||
|
session_max = Size(L"session_max", 1000000);
|
||||||
|
session_cookie_encode = Bool(L"session_cookie_encode", false);
|
||||||
|
session_keys_file = Text(L"session_keys_file");
|
||||||
|
session_allow_index_difference = Size(L"session_allow_index_difference", 8);
|
||||||
|
session_index_time_increment = Long(L"session_index_time_increment", 30);
|
||||||
|
session_key_renew_time = Size(L"session_key_renew_time", 172800); // 2 days
|
||||||
|
broken_encoded_cookie_treshold = Size(L"broken_encoded_cookie_treshold", 2);
|
||||||
|
session_hijacking_treshold = Size(L"session_hijacking_treshold", 128);
|
||||||
|
no_session_cookie_treshold = Size(L"no_session_cookie_treshold", 128);
|
||||||
|
no_session_cookie_ban_mode = Int(L"no_session_cookie_ban_mode", 0);
|
||||||
|
|
||||||
|
compression = Bool(L"compression", true);
|
||||||
|
compression_page_min_size = Size(L"compression_page_min_size", 512);
|
||||||
|
compression_encoding = Int(L"compression_encoding", 20);
|
||||||
|
|
||||||
|
html_filter = Bool(L"html_filter", false);
|
||||||
|
html_filter_white_char_mode = Int(L"html_filter_white_char_mode", 2);
|
||||||
|
html_filter_wrap_line = Int(L"html_filter_wrap_line", 110);
|
||||||
|
html_filter_tabs = Size(L"html_filter_tabs", 2);
|
||||||
|
html_filter_orphans = Bool(L"html_filter_orphans", true);
|
||||||
|
html_filter_orphans_mode_str = Text(L"html_filter_orphans_mode_str", L"nbsp");
|
||||||
|
html_filter_nofilter_tag = Text(L"html_filter_nofilter_tag", L"nofilter");
|
||||||
|
|
||||||
|
locale_dir = Text(L"locale_dir");
|
||||||
|
locale_dir_default = Text(L"locale_dir_default");
|
||||||
|
locale_max_id = Size(L"locale_max_id", 100);
|
||||||
|
locale_default_id = Size(L"locale_default_id", 0);
|
||||||
|
ListText(L"locale_files", locale_files);
|
||||||
|
|
||||||
|
title_separator = Text(L"title_separator", L" / ");
|
||||||
|
|
||||||
|
send_file_mode = Int(L"send_file_mode", 0);
|
||||||
|
send_file_header = Text(L"send_file_header", L"X-SENDFILE");
|
||||||
|
send_file_relative_prefix = Text(L"send_file_relative_prefix", L"upload-files-internal");
|
||||||
|
|
||||||
|
editors_html_safe_mode = Bool(L"editors_html_safe_mode", true);
|
||||||
|
editors_html_safe_mode_skip_root = Bool(L"editors_html_safe_mode_skip_root", true);
|
||||||
|
|
||||||
|
plugins_dir = Text(L"plugins_dir", L"/usr/local/winix/plugins");
|
||||||
|
NoLastSlash(plugins_dir);
|
||||||
|
ListText(L"plugins", plugin_file);
|
||||||
|
|
||||||
|
symlinks_follow_max = Size(L"symlinks_follow_max", 20);
|
||||||
|
|
||||||
|
ticket_form_prefix = Text(L"ticket_form_prefix", L"ticketparam");
|
||||||
|
|
||||||
|
pass_min_size = Size(L"pass_min_size", 5);
|
||||||
|
pass_type = Int(L"pass_type", 12);
|
||||||
|
pass_hash_use_salt = Bool(L"pass_hash_use_salt", false);
|
||||||
|
pass_hash_salt = Text(L"pass_hash_salt");
|
||||||
|
pass_use_rsa = Bool(L"pass_use_rsa", false);
|
||||||
|
pass_rsa_private_key = Text(L"pass_rsa_private_key");
|
||||||
|
|
||||||
|
opensll_path = Text(L"opensll_path", L"/usr/bin/openssl");
|
||||||
|
|
||||||
|
pattern_cacher_when_delete = Size(L"pattern_cacher_when_delete", 130);
|
||||||
|
pattern_cacher_how_many_delete = Size(L"pattern_cacher_how_many_delete", 30);
|
||||||
|
|
||||||
|
content_type_header = Int(L"content_type_header", 0);
|
||||||
|
umask = Int(L"umask", 0222);
|
||||||
|
|
||||||
|
ezc_max_elements = Size(L"ezc_max_elements", 50000);
|
||||||
|
ezc_max_loop_elements = Size(L"ezc_max_loop_elements", 5000);
|
||||||
|
ezc_out_streams_size = Size(L"ezc_out_streams_size", 128);
|
||||||
|
request_frame_parameter = Text(L"request_frame_parameter", L"frame");
|
||||||
|
request_all_frames_parameter = Text(L"request_all_frames_parameter", L"all_frames");
|
||||||
|
request_main_stream_parameter = Text(L"request_main_stream_parameter", L"main_stream");
|
||||||
|
|
||||||
|
request_frame_parameter_max_length = Size(L"request_frame_parameter_max_length", 128);
|
||||||
|
request_frame_parameter_max_frames = Size(L"request_frame_parameter_max_frames", 16);
|
||||||
|
|
||||||
|
xml_root = Text(L"xml_root", L"winix");
|
||||||
|
bin_stream_field = Text(L"bin_stream_field", L"bin_stream");
|
||||||
|
main_stream_field = Text(L"main_stream_field", L"main_stream");
|
||||||
|
ezc_frames_field = Text(L"ezc_frames_field", L"ezc_frames");
|
||||||
|
request_max_accept_fields = Size(L"request_max_accept_fields", 8);
|
||||||
|
request_max_accept_language_fields = Size(L"request_max_accept_language_fields", 8);
|
||||||
|
|
||||||
|
|
||||||
|
account_need_email_verification = Bool(L"account_need_email_verification", true);
|
||||||
|
reset_password_code_expiration_time = Long(L"reset_password_code_expiration_time", 86400);
|
||||||
|
|
||||||
|
time_zone_default_id = Size(L"time_zone_default_id", 34);
|
||||||
|
time_zone_max_id = Size(L"time_zone_max_id", 130);
|
||||||
|
|
||||||
|
etc_dir = Text(L"etc_dir", L"");
|
||||||
|
time_zones_file = Text(L"time_zones_file", L"time_zones.conf");
|
||||||
|
|
||||||
|
use_ban_list = Bool(L"use_ban_list", true);
|
||||||
|
ban_list_soft_max_size = Size(L"ban_list_soft_max_size", 50000);
|
||||||
|
ban_list_max_size = Size(L"ban_list_max_size", 51000);
|
||||||
|
ban_level_1_delay = Size(L"ban_level_1_delay", 1800);
|
||||||
|
ban_level_2_delay = Size(L"ban_level_2_delay", 86400);
|
||||||
|
ban_level_3_delay = Size(L"ban_level_3_delay", 604800);
|
||||||
|
|
||||||
|
incorrect_login_min_time_between_get_post = Size(L"incorrect_login_min_time_between_get_post", 2);
|
||||||
|
incorrect_login_captcha_treshold = Size(L"incorrect_login_captcha_treshold", 3);
|
||||||
|
incorrect_login_cannot_login_mode = Int(L"incorrect_login_cannot_login_mode", 0);
|
||||||
|
incorrect_login_cannot_login_treshold = Size(L"incorrect_login_cannot_login_treshold", 20);
|
||||||
|
incorrect_login_cannot_login_delay = Size(L"incorrect_login_cannot_login_delay", 1800);
|
||||||
|
|
||||||
|
pid_file = Text(L"pid_file", L"");
|
||||||
|
allow_ezc_frames_in_executable_items = Bool(L"allow_ezc_frames_in_executable_items", false);
|
||||||
|
|
||||||
|
check_proxy_ip_header = Bool(L"check_proxy_ip_header", false);
|
||||||
|
proxy_ip_header = Text(L"proxy_ip_header", L"X_Real_IP");
|
||||||
|
|
||||||
|
use_antispam_mechanism_for_not_logged_users = Bool(L"use_antispam_mechanism_for_not_logged_users", true);
|
||||||
|
antispam_list_max_size = Size(L"antispam_list_max_size", 10);
|
||||||
|
add_header_cache_no_store_in_htmx_request = Bool(L"add_header_cache_no_store_in_htmx_request", true);
|
||||||
|
|
||||||
|
request_queue_job_limit = Size(L"request_queue_job_limit", 1024);
|
||||||
|
|
||||||
|
ListText(L"allowed_origins", allowed_origins);
|
||||||
|
allow_all_origins = Bool(L"allow_all_origins", true);
|
||||||
|
are_cors_preflight_requests_available = Bool(L"are_cors_preflight_requests_available", false);
|
||||||
|
ListText(L"access_control_expose_headers", access_control_expose_headers);
|
||||||
|
access_control_allow_credentials = Bool(L"access_control_allow_credentials", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Config::SetAdditionalVariables()
|
||||||
|
{
|
||||||
|
for(size_t i=0 ; i<static_dirs.size() ; ++i)
|
||||||
|
NoLastSlash(static_dirs[i]);
|
||||||
|
|
||||||
|
CheckPasswd();
|
||||||
|
|
||||||
|
if( content_type_header < 0 || content_type_header > 2 )
|
||||||
|
content_type_header = 0;
|
||||||
|
|
||||||
|
if( locale_default_id > locale_max_id )
|
||||||
|
locale_default_id = locale_max_id;
|
||||||
|
|
||||||
|
if( locale_files.empty() )
|
||||||
|
locale_files.push_back(L"en");
|
||||||
|
|
||||||
|
if( !upload_group.empty() )
|
||||||
|
upload_group_int = GetGroupId(upload_group);
|
||||||
|
else
|
||||||
|
upload_group_int = -1;
|
||||||
|
|
||||||
|
if( session_cookie_encode && session_keys_file.empty() )
|
||||||
|
session_cookie_encode = false;
|
||||||
|
|
||||||
|
if( session_index_time_increment < 0 )
|
||||||
|
session_index_time_increment = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Config::CheckPasswd()
|
||||||
|
{
|
||||||
|
switch(pass_type)
|
||||||
|
{
|
||||||
|
case WINIX_CRYPT_HASH_NONE:
|
||||||
|
case WINIX_CRYPT_HASH_MD4:
|
||||||
|
case WINIX_CRYPT_HASH_MD5:
|
||||||
|
case WINIX_CRYPT_HASH_SHA1:
|
||||||
|
case WINIX_CRYPT_HASH_SHA224:
|
||||||
|
case WINIX_CRYPT_HASH_SHA256:
|
||||||
|
case WINIX_CRYPT_HASH_SHA384:
|
||||||
|
case WINIX_CRYPT_HASH_SHA512:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
pass_type = WINIX_CRYPT_HASH_SHA256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::wstring Config::Text(const wchar_t * name)
|
||||||
|
{
|
||||||
|
return space.to_wstr(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::wstring Config::Text(const wchar_t * name, const wchar_t * def)
|
||||||
|
{
|
||||||
|
return space.to_wstr(name, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::wstring Config::Text(const std::wstring & name, const wchar_t * def)
|
||||||
|
{
|
||||||
|
return space.to_wstr(name, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Config::Int(const wchar_t * name)
|
||||||
|
{
|
||||||
|
return space.to_int(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Config::Int(const wchar_t * name, int def)
|
||||||
|
{
|
||||||
|
return space.to_int(name, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Config::Int(const std::wstring & name, int def)
|
||||||
|
{
|
||||||
|
return space.to_int(name, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long Config::Long(const wchar_t * name)
|
||||||
|
{
|
||||||
|
return space.to_long(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
long Config::Long(const wchar_t * name, long def)
|
||||||
|
{
|
||||||
|
return space.to_long(name, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
long Config::Long(const std::wstring & name, long def)
|
||||||
|
{
|
||||||
|
return space.to_long(name, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
size_t Config::Size(const wchar_t * name)
|
||||||
|
{
|
||||||
|
return space.to_ulong(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t Config::Size(const wchar_t * name, size_t def)
|
||||||
|
{
|
||||||
|
return space.to_ulong(name, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t Config::Size(const std::wstring & name, size_t def)
|
||||||
|
{
|
||||||
|
return space.to_ulong(name, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Config::Bool(const wchar_t * name)
|
||||||
|
{
|
||||||
|
return space.to_bool(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Config::Bool(const wchar_t * name, bool def)
|
||||||
|
{
|
||||||
|
return space.to_bool(name, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Config::Bool(const std::wstring & name, bool def)
|
||||||
|
{
|
||||||
|
return space.to_bool(name, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Config::ListText(const wchar_t * name, std::vector<std::wstring> & list)
|
||||||
|
{
|
||||||
|
return space.to_list(name, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Config::ListText(const std::wstring & name, std::vector<std::wstring> & list)
|
||||||
|
{
|
||||||
|
return space.to_list(name, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Config::HasValue(const wchar_t * name, const wchar_t * value)
|
||||||
|
{
|
||||||
|
return space.has_value(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Config::HasValue(const std::wstring & name, const std::wstring & value)
|
||||||
|
{
|
||||||
|
return space.has_value(name.c_str(), value.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//void Config::Print(std::wostream & out)
|
||||||
|
//{
|
||||||
|
// space.serialize_to_space_stream(out);
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2014, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_cookieparser
|
||||||
|
#define headerfile_winix_core_cookieparser
|
||||||
|
|
||||||
|
#include "httpsimpleparser.h"
|
||||||
|
#include "requesttypes.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CookieParser : public HttpSimpleParser
|
||||||
|
{
|
||||||
|
|
||||||
|
const wchar_t * cookie_string;
|
||||||
|
CookieTab * cookie_tab;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
virtual int GetChar()
|
||||||
|
{
|
||||||
|
if( !cookie_string || *cookie_string == 0 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return (int)*(cookie_string++);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
virtual void Parameter(std::wstring & name, std::wstring & value)
|
||||||
|
{
|
||||||
|
// Cookie names are case insensitive according to section 3.1 of RFC 2965
|
||||||
|
// (we don't use locale here)
|
||||||
|
ToLower(name);
|
||||||
|
|
||||||
|
std::pair<CookieTab::iterator, bool> res = cookie_tab->insert( std::make_pair(name, value) );
|
||||||
|
log << log2 << "Cookie, name: \"" << name << "\", value: \"" << value << "\"";
|
||||||
|
|
||||||
|
if( res.second == false )
|
||||||
|
{
|
||||||
|
res.first->second = value;
|
||||||
|
log << " (overwritten)";
|
||||||
|
}
|
||||||
|
|
||||||
|
log << logend;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
CookieParser()
|
||||||
|
{
|
||||||
|
HttpSimpleParser::separator = ';';
|
||||||
|
HttpSimpleParser::value_can_be_quoted = true;
|
||||||
|
HttpSimpleParser::skip_white_chars = true;
|
||||||
|
HttpSimpleParser::recognize_special_chars = false;
|
||||||
|
HttpSimpleParser::getchar_returns_utf8_chars = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// cookie_string can be null
|
||||||
|
void Parse(const wchar_t * cookie_string_, CookieTab & cookie_tab_)
|
||||||
|
{
|
||||||
|
cookie_string = cookie_string_;
|
||||||
|
cookie_tab = &cookie_tab_;
|
||||||
|
|
||||||
|
HttpSimpleParser::Parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Parse(const std::wstring & cookie_string_, CookieTab & cookie_tab_)
|
||||||
|
{
|
||||||
|
Parse(cookie_string_.c_str(), cookie_tab_);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,360 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011-2021, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include "crypt.h"
|
||||||
|
#include "utf8/utf8.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//void Crypt::SetConfig(Config * pconfig)
|
||||||
|
//{
|
||||||
|
// config = pconfig;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
void Crypt::set_dependency(WinixBase * winix_base)
|
||||||
|
{
|
||||||
|
WinixBase::set_dependency(winix_base);
|
||||||
|
run.set_dependency(winix_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char Crypt::ConvertToHexForm(int val)
|
||||||
|
{
|
||||||
|
if( val < 10 )
|
||||||
|
return val + '0';
|
||||||
|
|
||||||
|
return val - 10 + 'a';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::HashBin(int hash, const char * in, size_t inlen, std::string & out)
|
||||||
|
{
|
||||||
|
out.clear();
|
||||||
|
|
||||||
|
if( !config )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
run.Clear();
|
||||||
|
run.set_dependency(this);
|
||||||
|
pt::wide_to_utf8(config->opensll_path, command);
|
||||||
|
run.Cmd(command);
|
||||||
|
run.Par("dgst");
|
||||||
|
run.Par("-binary");
|
||||||
|
|
||||||
|
switch(hash)
|
||||||
|
{
|
||||||
|
case WINIX_CRYPT_HASH_MD4: run.Par("-md4"); break;
|
||||||
|
case WINIX_CRYPT_HASH_MD5: run.Par("-md5"); break;
|
||||||
|
case WINIX_CRYPT_HASH_SHA1: run.Par("-sha1"); break;
|
||||||
|
case WINIX_CRYPT_HASH_SHA224: run.Par("-sha224"); break;
|
||||||
|
case WINIX_CRYPT_HASH_SHA256: run.Par("-sha256"); break;
|
||||||
|
case WINIX_CRYPT_HASH_SHA384: run.Par("-sha384"); break;
|
||||||
|
case WINIX_CRYPT_HASH_SHA512: run.Par("-sha512"); break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return run.Go(in, inlen, out) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::HashBin(int hash, const char * in, std::string & out)
|
||||||
|
{
|
||||||
|
size_t len = strlen(in);
|
||||||
|
return HashBin(hash, in, len, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::HashBin(int hash, const std::string & in, std::string & out)
|
||||||
|
{
|
||||||
|
return HashBin(hash, in.c_str(), in.size(), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::HashBin(int hash, const wchar_t * in, size_t inlen, std::string & out)
|
||||||
|
{
|
||||||
|
pt::wide_to_utf8(in, inlen, bufina);
|
||||||
|
int res = HashBin(hash, bufina.c_str(), bufina.size(), out);
|
||||||
|
bufina.clear();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::HashBin(int hash, const wchar_t * in, std::string & out)
|
||||||
|
{
|
||||||
|
size_t len = wcslen(in);
|
||||||
|
return HashBin(hash, in, len, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::HashBin(int hash, const std::wstring & in, std::string & out)
|
||||||
|
{
|
||||||
|
return HashBin(hash, in.c_str(), in.size(), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::HashHex(int hash, const char * in, size_t inlen, std::string & out)
|
||||||
|
{
|
||||||
|
int res = HashBin(hash, in, inlen, out_temp);
|
||||||
|
|
||||||
|
ConvertToHexForm(out_temp, out);
|
||||||
|
out_temp.clear();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::HashHex(int hash, const char * in, std::string & out)
|
||||||
|
{
|
||||||
|
size_t len = strlen(in);
|
||||||
|
return HashHex(hash, in, len, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::HashHex(int hash, const std::string & in, std::string & out)
|
||||||
|
{
|
||||||
|
return HashHex(hash, in.c_str(), in.size(), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::HashHex(int hash, const wchar_t * in, size_t inlen, std::wstring & out)
|
||||||
|
{
|
||||||
|
int res = HashBin(hash, in, inlen, out_temp);
|
||||||
|
|
||||||
|
ConvertToHexForm(out_temp, out);
|
||||||
|
out_temp.clear();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::HashHex(int hash, const wchar_t * in, std::wstring & out)
|
||||||
|
{
|
||||||
|
size_t len = wcslen(in);
|
||||||
|
return HashHex(hash, in, len, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::HashHex(int hash, const std::wstring & in, std::wstring & out)
|
||||||
|
{
|
||||||
|
return HashHex(hash, in.c_str(), in.size(), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsAllWhite(const char * str)
|
||||||
|
{
|
||||||
|
for( ; *str ; ++str)
|
||||||
|
{
|
||||||
|
if( !(IsWhite(*str) || *str==10) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::RSA(bool encrypt, const char * keypath, const char * in, size_t inlen, std::string & out)
|
||||||
|
{
|
||||||
|
out.clear();
|
||||||
|
|
||||||
|
if( !config || IsAllWhite(keypath) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
run.Clear();
|
||||||
|
pt::wide_to_utf8(config->opensll_path, command);
|
||||||
|
run.Cmd(command);
|
||||||
|
|
||||||
|
run.Par("rsautl");
|
||||||
|
run.Par("-inkey");
|
||||||
|
run.Par(keypath);
|
||||||
|
|
||||||
|
if(encrypt)
|
||||||
|
run.Par("-encrypt");
|
||||||
|
else
|
||||||
|
run.Par("-decrypt");
|
||||||
|
|
||||||
|
return run.Go(in, inlen, out) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::RSA(bool encrypt, const char * keypath, const std::string & in, std::string & out)
|
||||||
|
{
|
||||||
|
return RSA(encrypt, keypath, in.c_str(), in.size(), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::RSA(bool encrypt, const std::string & keypath, const std::string & in, std::string & out)
|
||||||
|
{
|
||||||
|
return RSA(encrypt, keypath.c_str(), in.c_str(), in.size(), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::RSA(bool encrypt, const wchar_t * keypath, const char * in, size_t inlen, std::string & out)
|
||||||
|
{
|
||||||
|
pt::wide_to_utf8(keypath, keypatha);
|
||||||
|
return RSA(encrypt, keypatha.c_str(), in, inlen, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::RSA(bool encrypt, const wchar_t * keypath, const std::string & in, std::string & out)
|
||||||
|
{
|
||||||
|
return RSA(encrypt, keypath, in.c_str(), in.size(), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::RSA(bool encrypt, const std::wstring & keypath, const std::string & in, std::string & out)
|
||||||
|
{
|
||||||
|
return RSA(encrypt, keypath.c_str(), in.c_str(), in.size(), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::PassHash(const std::wstring & salt, User & user)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
user.is_pass_hash_salted = false;
|
||||||
|
|
||||||
|
if( user.pass_type != WINIX_CRYPT_HASH_NONE )
|
||||||
|
{
|
||||||
|
pass_org = user.password;
|
||||||
|
pass_salted = user.password;
|
||||||
|
pass_salted += salt;
|
||||||
|
|
||||||
|
if( HashHex(user.pass_type, pass_salted, user.password) )
|
||||||
|
{
|
||||||
|
if( !salt.empty() )
|
||||||
|
user.is_pass_hash_salted = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log << log1 << "Crypt: problem with generating a hash, the password will not be hashed" << logend;
|
||||||
|
|
||||||
|
user.password = pass_org;
|
||||||
|
user.pass_type = WINIX_CRYPT_HASH_NONE;
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearString(pass_salted);
|
||||||
|
ClearString(pass_org);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Crypt::PassCrypt(const std::wstring & path_to_rsa_private_key, User & user)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
ClearString(user.pass_encrypted);
|
||||||
|
|
||||||
|
if( !path_to_rsa_private_key.empty() )
|
||||||
|
{
|
||||||
|
pt::wide_to_utf8(user.password, passa);
|
||||||
|
|
||||||
|
if( RSA(true, path_to_rsa_private_key, passa, user.pass_encrypted) )
|
||||||
|
{
|
||||||
|
ClearString(user.password);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClearString(user.pass_encrypted);
|
||||||
|
log << log1 << "AddUser: problem with encrypting, the password will not be encrypted!" << logend;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearString(passa);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Crypt::PassHashCrypt(const std::wstring & salt, const std::wstring & path_to_rsa_private_key, User & user)
|
||||||
|
{
|
||||||
|
PassHash(salt, user);
|
||||||
|
PassCrypt(path_to_rsa_private_key, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we hashing user.password, may it would be better to get the password as a seperate argument?
|
||||||
|
*/
|
||||||
|
void Crypt::PassHashCrypt(User & user)
|
||||||
|
{
|
||||||
|
user.pass_type = config->pass_type;
|
||||||
|
ClearString(user.pass_encrypted);
|
||||||
|
empty.clear();
|
||||||
|
|
||||||
|
if( config->pass_hash_use_salt && !config->pass_hash_salt.empty() )
|
||||||
|
PassHash(config->pass_hash_salt, user);
|
||||||
|
else
|
||||||
|
PassHash(empty, user);
|
||||||
|
|
||||||
|
|
||||||
|
if( config->pass_use_rsa && !config->pass_rsa_private_key.empty() )
|
||||||
|
PassCrypt(config->pass_rsa_private_key, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
@@ -0,0 +1,299 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011-2021, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_crypt
|
||||||
|
#define headerfile_winix_core_crypt
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "run.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "models/user.h"
|
||||||
|
#include "winixbase.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
the kind of hashes we are able to obtain in winix
|
||||||
|
*/
|
||||||
|
#define WINIX_CRYPT_HASH_NONE 0
|
||||||
|
#define WINIX_CRYPT_HASH_MD4 1
|
||||||
|
#define WINIX_CRYPT_HASH_MD5 2
|
||||||
|
#define WINIX_CRYPT_HASH_SHA1 10
|
||||||
|
#define WINIX_CRYPT_HASH_SHA224 11
|
||||||
|
#define WINIX_CRYPT_HASH_SHA256 12
|
||||||
|
#define WINIX_CRYPT_HASH_SHA384 13
|
||||||
|
#define WINIX_CRYPT_HASH_SHA512 14
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
calculating hashes, encrypting and decrypting with RSA
|
||||||
|
*/
|
||||||
|
class Crypt : public WinixBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
void set_dependency(WinixBase * winix_base);
|
||||||
|
|
||||||
|
|
||||||
|
//void SetConfig(Config * pconfig);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
calculating a hash from a given input
|
||||||
|
|
||||||
|
input:
|
||||||
|
hash - the kind of the hash - WINIX_CRYPT_HASH_*
|
||||||
|
in - input buffer
|
||||||
|
inlen - the length of the buffer
|
||||||
|
output:
|
||||||
|
out - the hash in binary form
|
||||||
|
*/
|
||||||
|
bool HashBin(int hash, const char * in, size_t inlen, std::string & out);
|
||||||
|
bool HashBin(int hash, const char * in, std::string & out);
|
||||||
|
bool HashBin(int hash, const std::string & in, std::string & out);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
calculating a hash from a given input
|
||||||
|
the input string is first changed to UTF8 and then hash is calculated
|
||||||
|
|
||||||
|
input:
|
||||||
|
hash - the kind of the hash - WINIX_CRYPT_HASH_*
|
||||||
|
in - input buffer
|
||||||
|
inlen - the length of the buffer
|
||||||
|
output:
|
||||||
|
out - the hash in binary form
|
||||||
|
*/
|
||||||
|
bool HashBin(int hash, const wchar_t * in, size_t inlen, std::string & out);
|
||||||
|
bool HashBin(int hash, const wchar_t * in, std::string & out);
|
||||||
|
bool HashBin(int hash, const std::wstring & in, std::string & out);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
calculating a hash from a given input
|
||||||
|
|
||||||
|
input:
|
||||||
|
hash - the kind of the hash - WINIX_CRYPT_HASH_*
|
||||||
|
in - input buffer
|
||||||
|
inlen - the length of the buffer
|
||||||
|
output:
|
||||||
|
out - the hash in the hex form (one byte is saved as two hex digits)
|
||||||
|
*/
|
||||||
|
bool HashHex(int hash, const char * in, size_t inlen, std::string & out);
|
||||||
|
bool HashHex(int hash, const char * in, std::string & out);
|
||||||
|
bool HashHex(int hash, const std::string & in, std::string & out);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
calculating a hash from a given input
|
||||||
|
the input string is first changed to UTF8 and then hash is calculated
|
||||||
|
|
||||||
|
input:
|
||||||
|
hash - the kind of the hash - WINIX_CRYPT_HASH_*
|
||||||
|
in - input buffer
|
||||||
|
inlen - the length of the buffer
|
||||||
|
output:
|
||||||
|
out - the hash in the hex form (one byte is saved as two hex digits)
|
||||||
|
the 'out' here is std::wstring (not std::string like beforehand)
|
||||||
|
*/
|
||||||
|
bool HashHex(int hash, const wchar_t * in, size_t inlen, std::wstring & out);
|
||||||
|
bool HashHex(int hash, const wchar_t * in, std::wstring & out);
|
||||||
|
bool HashHex(int hash, const std::wstring & in, std::wstring & out);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
encrypt/decrypt by using RSA algorithm
|
||||||
|
|
||||||
|
input:
|
||||||
|
encrypt - true means encrypting, false means decrypting
|
||||||
|
keypath - path to a RSA private key (this is a private and public key in one file)
|
||||||
|
in - input buffer
|
||||||
|
inlen - the size of the buffer
|
||||||
|
|
||||||
|
output:
|
||||||
|
out - encrypted or decrypted buffer (always binary)
|
||||||
|
*/
|
||||||
|
bool RSA(bool encrypt, const char * keypath, const char * in, size_t inlen, std::string & out);
|
||||||
|
bool RSA(bool encrypt, const char * keypath, const std::string & in, std::string & out);
|
||||||
|
bool RSA(bool encrypt, const std::string & keypath, const std::string & in, std::string & out);
|
||||||
|
bool RSA(bool encrypt, const wchar_t * keypath, const char * in, size_t inlen, std::string & out);
|
||||||
|
bool RSA(bool encrypt, const wchar_t * keypath, const std::string & in, std::string & out);
|
||||||
|
bool RSA(bool encrypt, const std::wstring & keypath, const std::string & in, std::string & out);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
this method creates a hash from the given plain text password
|
||||||
|
|
||||||
|
input.
|
||||||
|
salt - salt for the hash
|
||||||
|
up.pass_type - what kind of hash do you want - look at WINIX_CRYPT_HASH_* macros (in crypt.h)
|
||||||
|
up.pass - plain text password
|
||||||
|
|
||||||
|
if salt is empty then the hash will not be salted
|
||||||
|
|
||||||
|
output:
|
||||||
|
up.pass_type - (can be changed to 0 when there is a problem with generating a hash)
|
||||||
|
up.pass - hash from the password (or plain text if up.pass_type was zero)
|
||||||
|
up.pass_hash_salted (true if the hash is salted - when salt was not empty)
|
||||||
|
|
||||||
|
if there is a problem with generating a hash the method stores a plain text password
|
||||||
|
and changes up.pass_type to zero (plain text passwords are not salted)
|
||||||
|
*/
|
||||||
|
bool PassHash(const std::wstring & salt, User & user);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
this method encrypts the given password
|
||||||
|
|
||||||
|
input:
|
||||||
|
path_to_rsa_private_key - a path to rsa private key (this are a private and public keys both in one file)
|
||||||
|
up.pass - given password (can be a plain text or a hash)
|
||||||
|
|
||||||
|
if path_to_rsa_private_key is empty then the password will not be encrypted
|
||||||
|
|
||||||
|
output:
|
||||||
|
up.pass_encrypted
|
||||||
|
|
||||||
|
if there is a problem (or the path to the key is empty) then up.pass_encrypted will be empty
|
||||||
|
and the method returns false
|
||||||
|
*/
|
||||||
|
bool PassCrypt(const std::wstring & path_to_rsa_private_key, User & user);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
this method creates a hash from the given plain text password and then encrypts it
|
||||||
|
|
||||||
|
input:
|
||||||
|
salt - salt for the hash
|
||||||
|
path_to_rsa_private_key - a path to rsa private key (this are a private and public keys both in one file)
|
||||||
|
up.pass_type - what kind of hash do you want - look at WINIX_CRYPT_HASH_* macros (in crypt.h)
|
||||||
|
up.pass - plain text password
|
||||||
|
|
||||||
|
if salt is empty then the hash will not be salted
|
||||||
|
if path_to_rsa_private_key is empty then the password will not be encrypted
|
||||||
|
|
||||||
|
output:
|
||||||
|
up.pass_type - (can be changed to 0 when there is a problem with generating a hash)
|
||||||
|
up.pass - hash from the password (or plain text if up.pass_type was zero)
|
||||||
|
up.pass_hash_salted (true if the hash is salted - when salt was not empty)
|
||||||
|
up.pass_encrypted - encrypted password (if not empty)
|
||||||
|
|
||||||
|
*/
|
||||||
|
void PassHashCrypt(const std::wstring & salt, const std::wstring & path_to_rsa_private_key, User & user);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
this method creates a hash from the given plain text password and then encrypts it
|
||||||
|
|
||||||
|
input:
|
||||||
|
up.pass - plain text password
|
||||||
|
|
||||||
|
output:
|
||||||
|
up.pass_type - what kind of hash there is in up.pass
|
||||||
|
up.pass - hash from the password (or plain text if up.pass_type is zero)
|
||||||
|
up.pass_hash_salted - true if the hash is salted (plain text are never salted)
|
||||||
|
up.pass_encrypted - encrypted password (if not empty)
|
||||||
|
*/
|
||||||
|
void PassHashCrypt(User & user);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
putting some characters into the string and then calling clear()
|
||||||
|
*/
|
||||||
|
template<class StringType>
|
||||||
|
void ClearString(StringType & str);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//Config * config;
|
||||||
|
Run run;
|
||||||
|
std::string command, bufina, keypatha;
|
||||||
|
//std::wstring pass_salted;//, pass_hashed;
|
||||||
|
//std::string pass_hasheda, pass_encrypteda;
|
||||||
|
|
||||||
|
std::wstring pass_salted, pass_org;
|
||||||
|
std::string passa, out_temp;
|
||||||
|
std::wstring empty;
|
||||||
|
|
||||||
|
|
||||||
|
template<typename StringType>
|
||||||
|
void ConvertToHexForm(const std::string & in, StringType & out);
|
||||||
|
|
||||||
|
char ConvertToHexForm(int val);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename StringType>
|
||||||
|
void Crypt::ClearString(StringType & str)
|
||||||
|
{
|
||||||
|
for(size_t i=0 ; i<str.size() ; ++i)
|
||||||
|
str[i] = 0x0c;
|
||||||
|
|
||||||
|
str.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename StringType>
|
||||||
|
void Crypt::ConvertToHexForm(const std::string & in, StringType & out)
|
||||||
|
{
|
||||||
|
out.clear();
|
||||||
|
|
||||||
|
if( in.size() * 2 > out.capacity() )
|
||||||
|
out.reserve(in.size() * 2);
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<in.size() ; ++i)
|
||||||
|
{
|
||||||
|
out += ConvertToHexForm(((unsigned char)in[i]) >> 4);
|
||||||
|
out += ConvertToHexForm(((unsigned char)in[i]) & 0x0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_cur
|
||||||
|
#define headerfile_winix_core_cur
|
||||||
|
|
||||||
|
#include "request.h"
|
||||||
|
#include "session.h"
|
||||||
|
#include "mount.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
current request and session
|
||||||
|
*/
|
||||||
|
struct Cur
|
||||||
|
{
|
||||||
|
Request * request;
|
||||||
|
Session * session;
|
||||||
|
Mount * mount;
|
||||||
|
|
||||||
|
// those pointers are never null, if there is no a session for the user
|
||||||
|
// the 'session' pointer pointers at a special temporary session
|
||||||
|
|
||||||
|
Cur()
|
||||||
|
{
|
||||||
|
request = nullptr;
|
||||||
|
session = nullptr;
|
||||||
|
mount = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,376 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2014, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dircontainer.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::wstring DirContainer::dir_etc = L"etc";
|
||||||
|
std::wstring DirContainer::dir_var = L"var";
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::DirContainer()
|
||||||
|
{
|
||||||
|
is_root = false;
|
||||||
|
is_etc = false;
|
||||||
|
is_var = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::Iterator DirContainer::GetRoot()
|
||||||
|
{
|
||||||
|
if( !is_root )
|
||||||
|
return table.end();
|
||||||
|
|
||||||
|
return root_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::Iterator DirContainer::GetEtc()
|
||||||
|
{
|
||||||
|
if( !is_etc )
|
||||||
|
return table.end();
|
||||||
|
|
||||||
|
return etc_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::Iterator DirContainer::GetVar()
|
||||||
|
{
|
||||||
|
if( !is_var )
|
||||||
|
return table.end();
|
||||||
|
|
||||||
|
return var_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::ConstIterator DirContainer::Begin() const
|
||||||
|
{
|
||||||
|
return table.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::ConstIterator DirContainer::End() const
|
||||||
|
{
|
||||||
|
return table.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::SizeType DirContainer::Size()
|
||||||
|
{
|
||||||
|
return table.size(); // !! warning: it has O(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DirContainer::Empty()
|
||||||
|
{
|
||||||
|
return table.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DirContainer::IsNameOfSpecialFolder(const std::wstring & name)
|
||||||
|
{
|
||||||
|
return name == dir_etc || name == dir_var;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// looking for '/etc'
|
||||||
|
// 'root' is found beforehand
|
||||||
|
// CheckSpecialFolder() may not find everything (when the first is a special folder and then the root)
|
||||||
|
void DirContainer::FindSpecialFolders()
|
||||||
|
{
|
||||||
|
is_etc = false;
|
||||||
|
is_var = false;
|
||||||
|
|
||||||
|
if( !is_root )
|
||||||
|
return;
|
||||||
|
|
||||||
|
DirContainer::ParentIterator i = FindFirstChild(root_iter->id);
|
||||||
|
|
||||||
|
for( ; i!=ParentEnd() ; i = NextChild(i) )
|
||||||
|
{
|
||||||
|
if( i->second->url == dir_etc )
|
||||||
|
{
|
||||||
|
is_etc = true;
|
||||||
|
etc_iter = i->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( i->second->url == dir_var )
|
||||||
|
{
|
||||||
|
is_var = true;
|
||||||
|
var_iter = i->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// this is used with PushBack() method
|
||||||
|
void DirContainer::CheckSpecialFolder(const Item & item, Iterator iter)
|
||||||
|
{
|
||||||
|
if( item.parent_id == -1 )
|
||||||
|
{
|
||||||
|
is_root = true;
|
||||||
|
root_iter = iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !is_root )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( item.parent_id==root_iter->id && item.url==dir_etc )
|
||||||
|
{
|
||||||
|
is_etc = true;
|
||||||
|
etc_iter = iter;
|
||||||
|
log << log2 << "DirCont: added special folder: /etc" << logend;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( item.parent_id==root_iter->id && item.url==dir_var )
|
||||||
|
{
|
||||||
|
is_var = true;
|
||||||
|
var_iter = iter;
|
||||||
|
log << log2 << "DirCont: added special folder: /var" << logend;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::Iterator DirContainer::PushBack(const Item & item)
|
||||||
|
{
|
||||||
|
if( item.parent_id == -1 && is_root )
|
||||||
|
{
|
||||||
|
log << log1 << "DirCont: more than one root dir - skipped, id: " << item.id << logend;
|
||||||
|
return root_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator last_iter = table.insert(table.end(), item);
|
||||||
|
CheckSpecialFolder(item, last_iter);
|
||||||
|
|
||||||
|
log << log2 << "DirCont: added dir, url: " << item.url << ", id: " << item.id << ", parent_id: " << item.parent_id << logend;
|
||||||
|
|
||||||
|
table_id.insert( std::make_pair(last_iter->id, last_iter) );
|
||||||
|
table_parent.insert( std::make_pair(last_iter->parent_id, last_iter) );
|
||||||
|
|
||||||
|
log << log3 << "DirCont: added indexes to dir, id: " << last_iter->id << ", parent_id: " << last_iter->parent_id << logend;
|
||||||
|
|
||||||
|
return last_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool DirContainer::ChangeParent(long dir_id, long new_parent_id)
|
||||||
|
{
|
||||||
|
Iterator i = FindId(dir_id);
|
||||||
|
|
||||||
|
if( i == table.end() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( i->parent_id == new_parent_id )
|
||||||
|
return true; // nothing to do
|
||||||
|
|
||||||
|
ParentIterator p = FindFirstChild(i->parent_id);
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for( ; p != table_parent.end() ; p = NextChild(p) )
|
||||||
|
{
|
||||||
|
if( p->second->id == dir_id )
|
||||||
|
{
|
||||||
|
table_parent.erase(p);
|
||||||
|
log << log3 << "DirCont: removed parent index to dir: " << i->id << logend;
|
||||||
|
|
||||||
|
i->parent_id = new_parent_id;
|
||||||
|
table_parent.insert( std::make_pair(new_parent_id, i) );
|
||||||
|
log << log3 << "DirCont: added parent index to dir, id: " << i->id << ", parent_id: " << i->parent_id << logend;
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
if( IsNameOfSpecialFolder(i->url) )
|
||||||
|
FindSpecialFolders();
|
||||||
|
|
||||||
|
break; // that iterator (p) is only one
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !found )
|
||||||
|
log << log1 << "DirCont: cannot find parent_id: " << i->parent_id << " in parent indexes" << logend;
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void DirContainer::Clear()
|
||||||
|
{
|
||||||
|
table.clear();
|
||||||
|
table_id.clear();
|
||||||
|
table_parent.clear();
|
||||||
|
is_root = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::Iterator DirContainer::FindId(long id)
|
||||||
|
{
|
||||||
|
TableId::iterator i = table_id.find(id);
|
||||||
|
|
||||||
|
if( i == table_id.end() )
|
||||||
|
return table.end();
|
||||||
|
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::ConstIterator DirContainer::FindId(long id) const
|
||||||
|
{
|
||||||
|
TableId::const_iterator i = table_id.find(id);
|
||||||
|
|
||||||
|
if( i == table_id.end() )
|
||||||
|
return table.end();
|
||||||
|
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::ParentIterator DirContainer::ParentBegin()
|
||||||
|
{
|
||||||
|
return table_parent.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::ParentIterator DirContainer::ParentEnd()
|
||||||
|
{
|
||||||
|
return table_parent.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::ParentSizeType DirContainer::ParentSize()
|
||||||
|
{
|
||||||
|
return table_parent.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DirContainer::ParentEmpty()
|
||||||
|
{
|
||||||
|
return table_parent.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::ParentIterator DirContainer::FindFirstChild(long parent)
|
||||||
|
{
|
||||||
|
ParentIterator i = table_parent.lower_bound(parent);
|
||||||
|
|
||||||
|
if( i == table_parent.end() || i->first != parent )
|
||||||
|
return table_parent.end();
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::ParentIterator DirContainer::NextChild(ParentIterator i)
|
||||||
|
{
|
||||||
|
if( i == table_parent.end() )
|
||||||
|
return table_parent.end();
|
||||||
|
|
||||||
|
long parent = i->first;
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if( i == table_parent.end() || i->first != parent )
|
||||||
|
return table_parent.end();
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool DirContainer::DelById(long id)
|
||||||
|
{
|
||||||
|
TableId::iterator i = table_id.find(id);
|
||||||
|
|
||||||
|
if( i == table_id.end() )
|
||||||
|
{
|
||||||
|
log << log1 << "DirCont: delete: there is no directory with id: " << id << logend;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
long parent_id = i->second->parent_id;
|
||||||
|
TableParent::iterator z = table_parent.lower_bound(parent_id);
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for( ; z != table_parent.end() && z->first == parent_id ; ++z )
|
||||||
|
{
|
||||||
|
if( z->second == i->second )
|
||||||
|
{
|
||||||
|
log << log2 << "DirCont: deleted directory id: " << id << ", url: " << i->second->url;
|
||||||
|
|
||||||
|
if( i->second->parent_id == -1 )
|
||||||
|
{
|
||||||
|
log << log2 << " (root directory)";
|
||||||
|
is_root = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
log << log2 << logend;
|
||||||
|
|
||||||
|
table.erase(i->second);
|
||||||
|
|
||||||
|
log << log3 << "DirCont: deleted indexes into directory id: " << id << logend;
|
||||||
|
table_id.erase(i);
|
||||||
|
table_parent.erase(z);
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !found )
|
||||||
|
{
|
||||||
|
log << log1 << "DirCont: can't find an index_parent into directory id: " << id << ", url: " << i->second->url << " (deleting skipped)" << logend;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2021, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_dircontainer
|
||||||
|
#define headerfile_winix_core_dircontainer
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include "winixbase.h"
|
||||||
|
#include "models/item.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class DirContainer : public WinixBase
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef std::list<Item> Table;
|
||||||
|
typedef Table::iterator Iterator;
|
||||||
|
typedef Table::const_iterator ConstIterator;
|
||||||
|
typedef Table::size_type SizeType;
|
||||||
|
|
||||||
|
typedef std::map<long, Iterator> TableId;
|
||||||
|
typedef std::multimap<long, Iterator> TableParent;
|
||||||
|
typedef TableParent::iterator ParentIterator;
|
||||||
|
typedef TableParent::size_type ParentSizeType;
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer();
|
||||||
|
|
||||||
|
Iterator GetRoot();
|
||||||
|
Iterator GetEtc();
|
||||||
|
Iterator GetVar();
|
||||||
|
|
||||||
|
ConstIterator Begin() const;
|
||||||
|
ConstIterator End() const;
|
||||||
|
SizeType Size();
|
||||||
|
bool Empty();
|
||||||
|
Iterator PushBack(const Item & item);
|
||||||
|
bool ChangeParent(long dir_id, long new_parent_id);
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
Iterator FindId(long id);
|
||||||
|
ConstIterator FindId(long id) const;
|
||||||
|
|
||||||
|
bool DelById(long id);
|
||||||
|
|
||||||
|
ParentIterator ParentBegin(); // IMPROVE ME: may it should be renamed to ChildBegin() similarly as FindFirstChild() ?
|
||||||
|
ParentIterator ParentEnd();
|
||||||
|
ParentSizeType ParentSize();
|
||||||
|
bool ParentEmpty();
|
||||||
|
ParentIterator FindFirstChild(long parent);
|
||||||
|
ParentIterator NextChild(ParentIterator pi);
|
||||||
|
|
||||||
|
bool IsNameOfSpecialFolder(const std::wstring & name);
|
||||||
|
void FindSpecialFolders();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void CheckSpecialFolder(const Item & item, Iterator iter);
|
||||||
|
|
||||||
|
// main table with dirs
|
||||||
|
Table table;
|
||||||
|
|
||||||
|
// true if there is a root dir in the table
|
||||||
|
bool is_root;
|
||||||
|
|
||||||
|
// root
|
||||||
|
Iterator root_iter;
|
||||||
|
|
||||||
|
// true if there is a etc dir in the table
|
||||||
|
bool is_etc;
|
||||||
|
|
||||||
|
// etc
|
||||||
|
Iterator etc_iter;
|
||||||
|
|
||||||
|
// true if there is a var dir in the table
|
||||||
|
bool is_var;
|
||||||
|
|
||||||
|
// var
|
||||||
|
Iterator var_iter;
|
||||||
|
|
||||||
|
// indexes
|
||||||
|
TableId table_id;
|
||||||
|
TableParent table_parent;
|
||||||
|
|
||||||
|
// names of folders
|
||||||
|
static std::wstring dir_etc, dir_var;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,816 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
#include "dirs.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "notify/notify.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
void Dirs::SetCur(Cur * pcur)
|
||||||
|
{
|
||||||
|
cur = pcur;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Dirs::SetNotify(Notify * pnotify)
|
||||||
|
{
|
||||||
|
notify = pnotify;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Dirs::set_dependency(WinixModelDeprecated * winix_model)
|
||||||
|
{
|
||||||
|
WinixModelDeprecated::set_dependency(winix_model);
|
||||||
|
dir_tab.set_dependency(winix_model);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Dirs::Clear()
|
||||||
|
{
|
||||||
|
dir_tab.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Dirs::HasReadExecAccessForRoot(const Item & item)
|
||||||
|
{
|
||||||
|
// there must be at least one 'x' (for the root)
|
||||||
|
return (item.item_content.privileges & 01111) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Dirs::CheckRootDir()
|
||||||
|
{
|
||||||
|
DirContainer::Iterator i = dir_tab.GetRoot();
|
||||||
|
|
||||||
|
if( i != dir_tab.End() )
|
||||||
|
{
|
||||||
|
if( !HasReadExecAccessForRoot(*i) )
|
||||||
|
{
|
||||||
|
i->item_content.privileges = 07555;
|
||||||
|
log << log1 << "Dirs: there is no access for a root (admin) to the root dir, setting 07555 for the root directory" << logend;
|
||||||
|
i->item_content.set_connector(model_connector);
|
||||||
|
i->item_content.date_modification = std::time(nullptr);
|
||||||
|
i->item_content.save(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log << log1 << "Dirs: there is no a root directory in the database (creating one)" << logend;
|
||||||
|
|
||||||
|
ItemModelData item_data;
|
||||||
|
item_data.prepare_unique_url = false;
|
||||||
|
|
||||||
|
Item root;
|
||||||
|
root.set_connector(model_connector);
|
||||||
|
root.type = Item::dir;
|
||||||
|
root.parent_id = -1;
|
||||||
|
root.item_content.user_id = -1;
|
||||||
|
root.item_content.group_id = -1;
|
||||||
|
root.item_content.privileges = 07555;
|
||||||
|
root.item_content.date_creation = std::time(nullptr);
|
||||||
|
root.item_content.date_modification = root.item_content.date_creation;
|
||||||
|
|
||||||
|
if( root.insert(item_data) )
|
||||||
|
{
|
||||||
|
dir_tab.PushBack(root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Dirs::ReadDirs()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
|
||||||
|
//db->GetDirs(dir_tab);
|
||||||
|
morm::Finder<Item> finder(model_connector);
|
||||||
|
std::list<Item> all_dirs = finder.select().where().eq(L"type", static_cast<int>(Item::Type::dir)).get_list();
|
||||||
|
|
||||||
|
for(Item & item : all_dirs)
|
||||||
|
{
|
||||||
|
dir_tab.PushBack(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckRootDir();
|
||||||
|
dir_tab.FindSpecialFolders();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Dirs::ExtractName(const wchar_t * & s, std::wstring & name)
|
||||||
|
{
|
||||||
|
name.clear();
|
||||||
|
|
||||||
|
// skipping first slashes (can be more than one)
|
||||||
|
for( ; *s == '/' ; ++s);
|
||||||
|
|
||||||
|
for( ; *s != 0 && *s != '/' ; ++s)
|
||||||
|
name += *s;
|
||||||
|
|
||||||
|
return !name.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Dirs::IsDir(long id)
|
||||||
|
{
|
||||||
|
DirContainer::Iterator i = dir_tab.FindId(id);
|
||||||
|
|
||||||
|
if( i == dir_tab.End() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// !! dac clearowanie childs_tab
|
||||||
|
// !! ewentualnie mozna dodac trzeci domyslny parametr bool clear_tab = true
|
||||||
|
bool Dirs::GetDirChilds(long parent, std::vector<Item*> & childs_tab)
|
||||||
|
{
|
||||||
|
if( parent != -1 && !IsDir(parent) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DirContainer::ParentIterator i = dir_tab.FindFirstChild(parent);
|
||||||
|
|
||||||
|
for( ; i != dir_tab.ParentEnd() ; i = dir_tab.NextChild(i) )
|
||||||
|
childs_tab.push_back( &(*i->second) );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::ParentIterator Dirs::FindFirstChild(long parent_id)
|
||||||
|
{
|
||||||
|
DirContainer::ParentIterator i = dir_tab.FindFirstChild(parent_id);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::ParentIterator Dirs::NextChild(DirContainer::ParentIterator i)
|
||||||
|
{
|
||||||
|
return dir_tab.NextChild(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirContainer::ParentIterator Dirs::ParentEnd()
|
||||||
|
{
|
||||||
|
return dir_tab.ParentEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// !! dodatkowo moze metoda AppendPath dodajaca sciezke do biezacego stringa?
|
||||||
|
// albo tutaj stringa nie czyscic?
|
||||||
|
// O(m * log n) (m- how many parts are in 'id')
|
||||||
|
// path with a slash at the end and at the beginning
|
||||||
|
bool Dirs::MakePath(long id, std::wstring & path, bool clear_path)
|
||||||
|
{
|
||||||
|
DirContainer::Iterator i;
|
||||||
|
|
||||||
|
if( clear_path )
|
||||||
|
path.clear();
|
||||||
|
|
||||||
|
temp_path = '/';
|
||||||
|
|
||||||
|
while( true )
|
||||||
|
{
|
||||||
|
i = dir_tab.FindId(id);
|
||||||
|
|
||||||
|
if( i == dir_tab.End() ||
|
||||||
|
i->parent_id == id ) // means a loop (something wrong in the db)
|
||||||
|
{
|
||||||
|
// we don't change path if there is no such a directory
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( i->parent_id == -1 )
|
||||||
|
{
|
||||||
|
path += temp_path;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
id = i->parent_id;
|
||||||
|
|
||||||
|
temp_path.insert(0, i->url);
|
||||||
|
temp_path.insert(temp_path.begin(), '/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Dirs::MakePath(const std::vector<Item*> dir_tab, std::wstring & path, bool clear_path)
|
||||||
|
{
|
||||||
|
if( clear_path )
|
||||||
|
path.clear();
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<dir_tab.size() ; ++i)
|
||||||
|
{
|
||||||
|
path += dir_tab[i]->url;
|
||||||
|
path += '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
size_t Dirs::DirLevel(long id)
|
||||||
|
{
|
||||||
|
DirContainer::Iterator i;
|
||||||
|
size_t level = 0;
|
||||||
|
|
||||||
|
while( true )
|
||||||
|
{
|
||||||
|
i = dir_tab.FindId(id);
|
||||||
|
|
||||||
|
if( i == dir_tab.End() ||
|
||||||
|
i->parent_id == id ) // means a loop (something wrong in the db)
|
||||||
|
{
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( i->parent_id == -1 )
|
||||||
|
return level;
|
||||||
|
|
||||||
|
id = i->parent_id;
|
||||||
|
level += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Dirs::IsChild(long parent_id, long child_id)
|
||||||
|
{
|
||||||
|
if( child_id == parent_id )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DirContainer::Iterator i;
|
||||||
|
|
||||||
|
while( child_id != -1 )
|
||||||
|
{
|
||||||
|
i = dir_tab.FindId(child_id);
|
||||||
|
|
||||||
|
if( i == dir_tab.End() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( i->parent_id == parent_id )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
child_id = i->parent_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Dirs::ChangeParent(long dir_id, long new_parent_id)
|
||||||
|
{
|
||||||
|
return dir_tab.ChangeParent(dir_id, new_parent_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
checking whether dir_id has a parent parent_id (somewhere in the path)
|
||||||
|
*/
|
||||||
|
bool Dirs::HasParent(long dir_id, long parent_id)
|
||||||
|
{
|
||||||
|
DirContainer::Iterator i;
|
||||||
|
|
||||||
|
while( true )
|
||||||
|
{
|
||||||
|
i = dir_tab.FindId(dir_id);
|
||||||
|
|
||||||
|
if( i==dir_tab.End() || i->parent_id==-1 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( i->parent_id == parent_id )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
dir_id = i->parent_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Dirs::CreateDirTab(long dir_id, std::vector<Item*> & out_dir_tab)
|
||||||
|
{
|
||||||
|
DirContainer::Iterator i;
|
||||||
|
|
||||||
|
out_dir_tab.clear();
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
i = dir_tab.FindId(dir_id);
|
||||||
|
|
||||||
|
if( i == dir_tab.End() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( out_dir_tab.empty() )
|
||||||
|
out_dir_tab.insert(out_dir_tab.end(), &(*i)); // !! I am not sure whether begin() can be used on an empty container
|
||||||
|
else
|
||||||
|
out_dir_tab.insert(out_dir_tab.begin(), &(*i));
|
||||||
|
|
||||||
|
dir_id = i->parent_id;
|
||||||
|
}
|
||||||
|
while( dir_id != -1 );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Item * Dirs::GetRootDir()
|
||||||
|
{
|
||||||
|
DirContainer::Iterator root = dir_tab.GetRoot();
|
||||||
|
|
||||||
|
if( root == dir_tab.End() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return &(*root);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item * Dirs::GetEtcDir()
|
||||||
|
{
|
||||||
|
DirContainer::Iterator etc = dir_tab.GetEtc();
|
||||||
|
|
||||||
|
if( etc == dir_tab.End() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return &(*etc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item * Dirs::GetVarDir()
|
||||||
|
{
|
||||||
|
DirContainer::Iterator etc = dir_tab.GetVar();
|
||||||
|
|
||||||
|
if( etc == dir_tab.End() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return &(*etc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item * Dirs::GetDir(const wchar_t * name, long parent)
|
||||||
|
{
|
||||||
|
DirContainer::ParentIterator i = dir_tab.FindFirstChild(parent);
|
||||||
|
|
||||||
|
for( ; i!=dir_tab.ParentEnd() ; i = dir_tab.NextChild(i) )
|
||||||
|
if( i->second->url == name )
|
||||||
|
return &(*i->second);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item * Dirs::GetDir(const std::wstring & name, long parent)
|
||||||
|
{
|
||||||
|
return GetDir(name.c_str(), parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Item * Dirs::GetDir(const wchar_t * path)
|
||||||
|
{
|
||||||
|
if( *path == 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
DirContainer::Iterator root = dir_tab.GetRoot();
|
||||||
|
|
||||||
|
if( root == dir_tab.End() )
|
||||||
|
// ops, we do not have a root dir
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Item * pitem = &(*root);
|
||||||
|
const wchar_t * s = path;
|
||||||
|
|
||||||
|
while( ExtractName(s, get_dir_temp) )
|
||||||
|
{
|
||||||
|
pitem = GetDir(get_dir_temp, pitem->id);
|
||||||
|
|
||||||
|
if( !pitem )
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pitem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Item * Dirs::GetDir(const std::wstring & path)
|
||||||
|
{
|
||||||
|
return GetDir(path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item * Dirs::GetDir(long id)
|
||||||
|
{
|
||||||
|
DirContainer::Iterator i = dir_tab.FindId(id);
|
||||||
|
|
||||||
|
if( i == dir_tab.End() )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &(*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Item * Dirs::GetDir(long id) const
|
||||||
|
{
|
||||||
|
DirContainer::ConstIterator i = dir_tab.FindId(id);
|
||||||
|
|
||||||
|
if( i == dir_tab.End() )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &(*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Item * Dirs::AddDir(const Item & item)
|
||||||
|
{
|
||||||
|
return &(*dir_tab.PushBack(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
size_t Dirs::AnalyzeDir(Item * pdir, const std::wstring & path, long & dir_id, std::wstring & dir)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
size_t old_i;
|
||||||
|
|
||||||
|
while( true )
|
||||||
|
{
|
||||||
|
dir_id = pdir->id;
|
||||||
|
|
||||||
|
// skipping slashes
|
||||||
|
for( ; i<path.size() && path[i] == '/' ; ++i );
|
||||||
|
|
||||||
|
if( i == path.size() )
|
||||||
|
return i; // end of the path
|
||||||
|
|
||||||
|
// creating a name
|
||||||
|
old_i = i;
|
||||||
|
analyze_temp.clear();
|
||||||
|
|
||||||
|
for( ; i<path.size() && path[i] != '/' ; ++i)
|
||||||
|
analyze_temp += path[i];
|
||||||
|
|
||||||
|
pdir = GetDir(analyze_temp, pdir->id);
|
||||||
|
|
||||||
|
if( !pdir )
|
||||||
|
return old_i; // analyze_temp is not a directory
|
||||||
|
|
||||||
|
dir += analyze_temp;
|
||||||
|
dir += '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
the path should begin with a slash
|
||||||
|
|
||||||
|
return values:
|
||||||
|
0 - directory exists
|
||||||
|
dir_id - id of the directory
|
||||||
|
dir - the path to the directory (with a slash at the end)
|
||||||
|
file - if not empty means a file name (we don't check if the file really exists)
|
||||||
|
1 - there is not a root dir
|
||||||
|
2 - the path is empty
|
||||||
|
3 - there is not such a directory
|
||||||
|
*/
|
||||||
|
int Dirs::AnalyzePath(const std::wstring & path, long & dir_id, std::wstring & dir, std::wstring & file)
|
||||||
|
{
|
||||||
|
Item * pdir = GetRootDir();
|
||||||
|
dir = '/';
|
||||||
|
file.clear();
|
||||||
|
|
||||||
|
if( !pdir )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if( path.empty() )
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
if( path[0] != '/' )
|
||||||
|
return 3;
|
||||||
|
|
||||||
|
size_t i = AnalyzeDir(pdir, path, dir_id, dir);
|
||||||
|
|
||||||
|
if( i < path.size() )
|
||||||
|
{
|
||||||
|
// checking if at least one slash has left
|
||||||
|
for(size_t a=i ; a < path.size() ; ++a)
|
||||||
|
if( path[a] == '/' )
|
||||||
|
return 3; // there is not such a directory
|
||||||
|
|
||||||
|
// the rest of the path is a file name
|
||||||
|
file = path.c_str() + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// current_dir_tab can be the same container as out_dir_tab
|
||||||
|
void Dirs::CopyDirTab(const std::vector<Item*> & in, std::vector<Item*> & out)
|
||||||
|
{
|
||||||
|
if( &in != &out )
|
||||||
|
{
|
||||||
|
out.resize(in.size());
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<in.size() ; ++i)
|
||||||
|
out[i] = in[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
!! IMPROVE ME
|
||||||
|
may dir_tab can be empty when link_to is not relative?
|
||||||
|
and now the algorith doesn't check if link_to is not relative (it only uses dir_tab)
|
||||||
|
*/
|
||||||
|
bool Dirs::AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_to, size_t & i)
|
||||||
|
{
|
||||||
|
size_t old_i;
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
if( dir_tab.empty() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while( true )
|
||||||
|
{
|
||||||
|
// skipping slashes
|
||||||
|
for( ; i<link_to.size() && link_to[i] == '/' ; ++i);
|
||||||
|
|
||||||
|
if( i == link_to.size() )
|
||||||
|
return true; // end of the path
|
||||||
|
|
||||||
|
// creating a name
|
||||||
|
old_i = i;
|
||||||
|
analyze_temp.clear();
|
||||||
|
|
||||||
|
for( ; i<link_to.size() && link_to[i] != '/' ; ++i)
|
||||||
|
analyze_temp += link_to[i];
|
||||||
|
|
||||||
|
if( analyze_temp == L".." )
|
||||||
|
{
|
||||||
|
if( dir_tab.size() <= 1 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
dir_tab.pop_back();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( analyze_temp != L"." )
|
||||||
|
{
|
||||||
|
Item * pdir = GetDir(analyze_temp, dir_tab.back()->id);
|
||||||
|
|
||||||
|
if( !pdir )
|
||||||
|
{
|
||||||
|
i = old_i;
|
||||||
|
return true; // analyze_temp is not a directory
|
||||||
|
}
|
||||||
|
|
||||||
|
dir_tab.push_back(pdir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int Dirs::FollowLink(std::vector<Item*> & dir_tab, const std::wstring & link_to, std::wstring & out_item)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if( !AnalyzeDir(dir_tab, link_to, i) )
|
||||||
|
return 2; // incorrect link_to
|
||||||
|
|
||||||
|
if( i < link_to.size() )
|
||||||
|
{
|
||||||
|
// checking if at least one slash has left
|
||||||
|
for(size_t a=i ; a < link_to.size() ; ++a)
|
||||||
|
if( link_to[a] == '/' )
|
||||||
|
return 2; // there is not such a directory
|
||||||
|
|
||||||
|
// the rest of the path is a file name
|
||||||
|
out_item = link_to.c_str() + i;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
return codes:
|
||||||
|
ok:
|
||||||
|
0 - the link_to is a path to a directory (out_item skipped, out_dir_tab will not be empty)
|
||||||
|
1 - the link_to is a path to a file (out_item is used, out_dir_tab will not be empty)
|
||||||
|
|
||||||
|
error:
|
||||||
|
2 - incorrect link_to
|
||||||
|
3 - there is not a root dir
|
||||||
|
4 - current_dir_tab was empty
|
||||||
|
|
||||||
|
current_dir_tab can be the same container as out_dir_tab
|
||||||
|
link_to can be a relative path (without the first slash) and can contain ".." or "."
|
||||||
|
*/
|
||||||
|
int Dirs::FollowLink(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
|
||||||
|
std::vector<Item*> & out_dir_tab, std::wstring & out_item)
|
||||||
|
{
|
||||||
|
temp_link_to = link_to; // link_to can be from the out_item and would be cleared next
|
||||||
|
out_item.clear();
|
||||||
|
|
||||||
|
if( current_dir_tab.empty() )
|
||||||
|
return 4;
|
||||||
|
|
||||||
|
if( temp_link_to.empty() )
|
||||||
|
{
|
||||||
|
CopyDirTab(current_dir_tab, out_dir_tab);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( temp_link_to[0] == '/' )
|
||||||
|
{
|
||||||
|
// temp_link_to is an absolute path
|
||||||
|
Item * pdir = GetRootDir();
|
||||||
|
|
||||||
|
if( !pdir )
|
||||||
|
return 3;
|
||||||
|
|
||||||
|
out_dir_tab.clear();
|
||||||
|
out_dir_tab.push_back(pdir);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// temp_link_to is a relative path
|
||||||
|
CopyDirTab(current_dir_tab, out_dir_tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FollowLink(out_dir_tab, temp_link_to, out_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Dirs::SplitPath(const std::wstring & path, std::wstring & dir, std::wstring & file)
|
||||||
|
{
|
||||||
|
std::wstring::size_type i;
|
||||||
|
|
||||||
|
dir.clear();
|
||||||
|
file.clear();
|
||||||
|
|
||||||
|
if( path.empty() )
|
||||||
|
// !! moze dir ustawic na '/' ?
|
||||||
|
return;
|
||||||
|
|
||||||
|
for( i=path.size()-1 ; i>0 && path[i]!='/' ; --i);
|
||||||
|
|
||||||
|
if( path[i] != '/' )
|
||||||
|
{
|
||||||
|
// we do not have any slashes '/'
|
||||||
|
file = path;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dir.assign(path, 0, i + 1); // +1 means with a slash at the end
|
||||||
|
|
||||||
|
if( i < path.size() - 1 )
|
||||||
|
file.assign(path, i+1, path.size() - i - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// !! dodac kasowanie z bazy
|
||||||
|
bool Dirs::DelDir(long dir_id)
|
||||||
|
{
|
||||||
|
return dir_tab.DelById(dir_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Dirs::AddDirectory(Item & item, bool add_to_dir_tab, Item ** pdir, int notify_code)
|
||||||
|
{
|
||||||
|
if( pdir )
|
||||||
|
*pdir = 0;
|
||||||
|
|
||||||
|
if( item.type != Item::dir )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//Error status = db->AddItem(item);
|
||||||
|
//item.set_connector(model_connector);
|
||||||
|
bool status = item.insert();
|
||||||
|
|
||||||
|
if( status )
|
||||||
|
{
|
||||||
|
Item * d = AddDir(item);
|
||||||
|
|
||||||
|
if( add_to_dir_tab && !cur->request->dir_tab.empty() && cur->request->dir_tab.back()->id == item.parent_id )
|
||||||
|
cur->request->dir_tab.push_back(d);
|
||||||
|
|
||||||
|
if( pdir )
|
||||||
|
*pdir = d;
|
||||||
|
|
||||||
|
if( notify_code )
|
||||||
|
notify->ItemChanged(notify_code, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Item * Dirs::CreateVarDir()
|
||||||
|
{
|
||||||
|
Item * var = GetVarDir();
|
||||||
|
|
||||||
|
if( var )
|
||||||
|
return var;
|
||||||
|
|
||||||
|
Item v;
|
||||||
|
Item * root = GetRootDir();
|
||||||
|
|
||||||
|
if( root )
|
||||||
|
{
|
||||||
|
v.set_connector(root->get_connector());
|
||||||
|
v.parent_id = root->id;
|
||||||
|
v.item_content.user_id = root->item_content.user_id;
|
||||||
|
v.item_content.group_id = root->item_content.group_id;
|
||||||
|
v.item_content.privileges = root->item_content.privileges;
|
||||||
|
v.subject = L"var";
|
||||||
|
v.url = L"var";
|
||||||
|
v.type = Item::dir;
|
||||||
|
|
||||||
|
AddDirectory(v, false, &var);
|
||||||
|
}
|
||||||
|
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// printing first and last slash
|
||||||
|
void Dirs::LogDir(const std::vector<Item*> & dir_tab)
|
||||||
|
{
|
||||||
|
log << '/';
|
||||||
|
|
||||||
|
// skipping the first (root) directory
|
||||||
|
for(size_t i=1 ; i<dir_tab.size() ; ++i)
|
||||||
|
log << dir_tab[i]->url << '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_dirs
|
||||||
|
#define headerfile_winix_core_dirs
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include "dircontainer.h"
|
||||||
|
#include "request.h"
|
||||||
|
#include "models/item.h"
|
||||||
|
#include "winixmodeldeprecated.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
class Notify;
|
||||||
|
|
||||||
|
// !! IMPROVE ME
|
||||||
|
// we do not support '..' in a path (for simplicity and security reasons)
|
||||||
|
// (we will support '..' in the future)
|
||||||
|
|
||||||
|
|
||||||
|
class Dirs : public WinixModelDeprecated
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void Clear();
|
||||||
|
void ReadDirs();
|
||||||
|
|
||||||
|
void SetCur(Cur * pcur);
|
||||||
|
void SetNotify(Notify * pnotify);
|
||||||
|
|
||||||
|
void set_dependency(WinixModelDeprecated * winix_model);
|
||||||
|
|
||||||
|
// these methods return false if there is no such a dir
|
||||||
|
bool IsDir(long dir_id);
|
||||||
|
bool GetDirChilds(long parent_id, std::vector<Item*> & childs_tab); // !! zamienic na GetChilds()
|
||||||
|
bool MakePath(long dir_id, std::wstring & path, bool clear_path = true);
|
||||||
|
void MakePath(const std::vector<Item*> dir_tab, std::wstring & path, bool clear_path = true);
|
||||||
|
bool ChangeParent(long dir_id, long new_parent_id);
|
||||||
|
|
||||||
|
bool HasParent(long dir_id, long parent_id);
|
||||||
|
|
||||||
|
bool DelDir(long dir_id);
|
||||||
|
|
||||||
|
// if returns true then out_dir_tab is not empty
|
||||||
|
bool CreateDirTab(long dir_id, std::vector<Item*> & out_dir_tab);
|
||||||
|
|
||||||
|
void LogDir(const std::vector<Item*> & dir_tab);
|
||||||
|
|
||||||
|
int AnalyzePath(const std::wstring & path, long & dir_id, std::wstring & dir, std::wstring & file);
|
||||||
|
int FollowLink(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
|
||||||
|
std::vector<Item*> & out_dir_tab, std::wstring & out_item);
|
||||||
|
static void SplitPath(const std::wstring & path, std::wstring & dir, std::wstring & file);
|
||||||
|
|
||||||
|
DirContainer::ParentIterator FindFirstChild(long parent_id);
|
||||||
|
DirContainer::ParentIterator NextChild(DirContainer::ParentIterator i);
|
||||||
|
DirContainer::ParentIterator ParentEnd(); // !! pozostalo do zamiany na child
|
||||||
|
|
||||||
|
|
||||||
|
// these methods return null if there is no such a dir
|
||||||
|
// !! zmienic nazwy wskazujace ze operujemy tylko na lokalnej tablicy
|
||||||
|
Item * GetRootDir();
|
||||||
|
Item * GetEtcDir();
|
||||||
|
Item * GetVarDir();
|
||||||
|
|
||||||
|
Item * GetDir(const wchar_t * name, long parent);
|
||||||
|
Item * GetDir(const std::wstring & name, long parent);
|
||||||
|
Item * GetDir(const wchar_t * path);
|
||||||
|
Item * GetDir(const std::wstring & path);
|
||||||
|
Item * GetDir(long id);
|
||||||
|
Item * AddDir(const Item & item);
|
||||||
|
|
||||||
|
const Item * GetDir(long id) const;
|
||||||
|
|
||||||
|
void CheckRootDir();
|
||||||
|
|
||||||
|
Item * CreateVarDir();
|
||||||
|
|
||||||
|
// !! jak juz wczesniejsze nazwy beda zmienione to tutaj damy AddDir() /AddDir() juz istnieje przeciez?/
|
||||||
|
bool AddDirectory(Item & item, bool add_to_dir_tab = false, Item ** pdir = 0, int notify_code = 0);
|
||||||
|
|
||||||
|
// returns how many levels of directories there are
|
||||||
|
// "/" -> 0 (root dir)
|
||||||
|
// "/abc" -> 1
|
||||||
|
// "/abc/def" -> 2
|
||||||
|
size_t DirLevel(long id);
|
||||||
|
|
||||||
|
// checking if child_id is really a child of parent_id
|
||||||
|
bool IsChild(long parent_id, long child_id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Cur * cur;
|
||||||
|
Notify * notify;
|
||||||
|
|
||||||
|
DirContainer dir_tab;
|
||||||
|
std::wstring temp_path;
|
||||||
|
std::wstring temp_link_to;
|
||||||
|
|
||||||
|
size_t AnalyzeDir(Item * pdir, const std::wstring & path, long & dir_id, std::wstring & dir);
|
||||||
|
bool AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_to, size_t & i);
|
||||||
|
std::wstring analyze_temp;
|
||||||
|
std::wstring get_dir_temp;
|
||||||
|
|
||||||
|
void CopyDirTab(const std::vector<Item*> & in, std::vector<Item*> & out);
|
||||||
|
int FollowLink(std::vector<Item*> & dir_tab, const std::wstring & link_to, std::wstring & out_item);
|
||||||
|
|
||||||
|
bool ExtractName(const wchar_t * & s, std::wstring & name);
|
||||||
|
bool HasReadExecAccessForRoot(const Item & item);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2014, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_error
|
||||||
|
#define headerfile_winix_core_error
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define WINIX_ERR_OK 0
|
||||||
|
//#define WINIX_ERR_INCORRECT_PATH 1
|
||||||
|
|
||||||
|
//#define WINIX_ERR_NO_POSTVAR 2
|
||||||
|
#define WINIX_ERR_INCORRECT_DIR 3
|
||||||
|
#define WINIX_ERR_CANT_CHANGE_USER 4
|
||||||
|
#define WINIX_ERR_CANT_CHANGE_GROUP 5
|
||||||
|
#define WINIX_ERR_CANT_CHANGE_PRIVILEGES 6
|
||||||
|
#define WINIX_ERR_PERMISSION_DENIED 7
|
||||||
|
#define WINIX_ERR_NO_ROOT_DIR 8
|
||||||
|
#define WINIX_ERR_NO_FUNCTION 9
|
||||||
|
|
||||||
|
|
||||||
|
#define WINIX_ERR_NO_ITEM 10
|
||||||
|
#define WINIX_ERR_UNKNOWN_PARAM 11
|
||||||
|
|
||||||
|
#define WINIX_ERR_MOUNT_UNKNOWN 12
|
||||||
|
#define WINIX_ERR_UNKNOWN_FILESYSTEM 13
|
||||||
|
#define WINIX_ERR_NO_MOUNTPOINT 14
|
||||||
|
//#define WINIX_ERR_MOUNT_NO_PARAM 15
|
||||||
|
|
||||||
|
#define WINIX_ERR_NO_THREAD 16
|
||||||
|
#define WINIX_ERR_EMPTY 17
|
||||||
|
#define WINIX_ERR_SPAM 18
|
||||||
|
#define WINIX_ERR_INCORRECT_REBUS 19
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define WINIX_ERR_NO_BOUNDARY 20
|
||||||
|
#define WINIX_ERR_BROKEN_INPUT 21
|
||||||
|
#define WINIX_ERR_INPUT_TOO_LARGE 22
|
||||||
|
#define WINIX_ERR_CANT_CREATE_FILE 23
|
||||||
|
|
||||||
|
#define WINIX_ERR_NO_TICKET 24
|
||||||
|
|
||||||
|
//#define WINIX_ERR_PASSWORDS_DIFFERENT 25
|
||||||
|
//#define WINIX_ERR_PASSWORD_TOO_SHORT 26
|
||||||
|
//#define WINIX_ERR_USER_EXISTS 27
|
||||||
|
//#define WINIX_ERR_LOGIN_EMPTY 28
|
||||||
|
#define WINIX_DIFFERENT_MOUNT_POINTS 29
|
||||||
|
|
||||||
|
|
||||||
|
#define WINIX_ERR_DB_FATAL_ERROR_DURING_CONNECTING 100
|
||||||
|
#define WINIX_ERR_DB_INCORRECT_QUERY 101
|
||||||
|
#define WINIX_ERR_DB_INCORRENT_RESULT_STATUS 102
|
||||||
|
#define WINIX_ERR_DB_NO_COLUMN 103
|
||||||
|
#define WINIX_ERR_DB_INCORRECT_LOGIN 104
|
||||||
|
#define WINIX_ERR_DB_MORE_THAN_ONE_LOGIN 105
|
||||||
|
#define WINIX_ERR_DB_ERR_CURRVAL 106
|
||||||
|
|
||||||
|
#define WINIX_ERR_FILE_EXPECTED 107
|
||||||
|
#define WINIX_ERR_DIR_EXPECTED 108
|
||||||
|
|
||||||
|
//#define WINIX_ERR_UNKNOWN 1000
|
||||||
|
#define WINIX_NOTHING_TO_DO 109
|
||||||
|
#define WINIX_ERR_INCORRECT_URI 110
|
||||||
|
|
||||||
|
#define WINIX_ERR_INTERNAL_ERROR 2000
|
||||||
|
|
||||||
|
|
||||||
|
typedef int Error;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "filelog.h"
|
||||||
|
#include <ctime>
|
||||||
|
#include <string.h>
|
||||||
|
#include "utf8/utf8.h"
|
||||||
|
#include "timezones.h"
|
||||||
|
#include "plugin.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FileLog::FileLog()
|
||||||
|
{
|
||||||
|
time_zones = nullptr;
|
||||||
|
synchro = nullptr;
|
||||||
|
plugin = nullptr;
|
||||||
|
log_time_zone_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FileLog::~FileLog()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileLog::set_synchro(Synchro * synchro)
|
||||||
|
{
|
||||||
|
this->synchro = synchro;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileLog::set_plugin(Plugin * plugin)
|
||||||
|
{
|
||||||
|
this->plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileLog::init(const std::wstring & log_file, bool log_stdout, int log_level, bool save_each_line, size_t log_time_zone_id)
|
||||||
|
{
|
||||||
|
pt::FileLog::init(log_file, log_stdout, log_level, save_each_line);
|
||||||
|
this->log_time_zone_id = log_time_zone_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileLog::set_time_zones(TimeZones * time_zones)
|
||||||
|
{
|
||||||
|
this->time_zones = time_zones;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int FileLog::get_log_level()
|
||||||
|
{
|
||||||
|
return log_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FileLog::should_save_each_line()
|
||||||
|
{
|
||||||
|
return save_each_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pt::Date FileLog::get_local_date(const pt::Date & date)
|
||||||
|
{
|
||||||
|
if( time_zones )
|
||||||
|
{
|
||||||
|
Lock lock(synchro);
|
||||||
|
TimeZone * tz = time_zones->GetZone(log_time_zone_id);
|
||||||
|
|
||||||
|
if( tz )
|
||||||
|
{
|
||||||
|
pt::Date local_date = tz->ToLocal(date);
|
||||||
|
return local_date;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FileLog::save_log(pt::WTextStream * buffer)
|
||||||
|
{
|
||||||
|
if( !buffer->empty() )
|
||||||
|
{
|
||||||
|
Lock lock(synchro);
|
||||||
|
pt::FileLog::save_log(buffer);
|
||||||
|
|
||||||
|
// at the beginning when winix starts the plugin pointer is null
|
||||||
|
// this plugin is set after the plugin object is initialized
|
||||||
|
if( plugin )
|
||||||
|
{
|
||||||
|
plugin->Call(WINIX_SAVE_FILELOG, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_filelog
|
||||||
|
#define headerfile_winix_core_filelog
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include "core/synchro.h"
|
||||||
|
#include "log/log.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
class TimeZones;
|
||||||
|
class Plugin;
|
||||||
|
|
||||||
|
class FileLog : public pt::FileLog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
FileLog();
|
||||||
|
virtual ~FileLog();
|
||||||
|
|
||||||
|
void set_synchro(Synchro * synchro);
|
||||||
|
void set_plugin(Plugin * plugin);
|
||||||
|
|
||||||
|
// using pt::FileLog::init to suppress clang warning:
|
||||||
|
// warning: 'Winix::FileLog::init' hides overloaded virtual function [-Woverloaded-virtual]
|
||||||
|
using pt::FileLog::init;
|
||||||
|
|
||||||
|
void init(const std::wstring & log_file, bool log_stdout, int log_level, bool save_each_line, size_t log_time_zone_id);
|
||||||
|
|
||||||
|
void set_time_zones(TimeZones * time_zones);
|
||||||
|
pt::Date get_local_date(const pt::Date & date);
|
||||||
|
|
||||||
|
int get_log_level();
|
||||||
|
bool should_save_each_line();
|
||||||
|
|
||||||
|
void save_log(pt::WTextStream * buffer);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
size_t log_time_zone_id;
|
||||||
|
|
||||||
|
TimeZones * time_zones;
|
||||||
|
Synchro * synchro;
|
||||||
|
Plugin * plugin; // can be null (only at the beginning when winix starts)
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2021, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "groups.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Groups::Groups()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Groups::set_dependency(WinixModelDeprecated * winix_model)
|
||||||
|
{
|
||||||
|
WinixModelDeprecated::set_dependency(winix_model);
|
||||||
|
table.set_dependency(winix_model);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Groups::Clear()
|
||||||
|
{
|
||||||
|
table.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Groups::ReadGroups()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
|
||||||
|
morm::Finder<Group> finder(model_connector);
|
||||||
|
|
||||||
|
std::vector<Group> groups_tmp = finder.
|
||||||
|
select().
|
||||||
|
get_vector();
|
||||||
|
|
||||||
|
for(Group & group : groups_tmp)
|
||||||
|
{
|
||||||
|
table.PushBack(group, group.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Group * Groups::GetGroup(long group_id)
|
||||||
|
{
|
||||||
|
Table::Iterator i = table.FindId(group_id);
|
||||||
|
|
||||||
|
if( i == table.End() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return &(*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Group * Groups::GetGroup(const std::wstring & name)
|
||||||
|
{
|
||||||
|
Table::Iterator i = table.FindName(name);
|
||||||
|
|
||||||
|
if( i == table.End() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return &(*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long Groups::GetGroupId(const std::wstring & name)
|
||||||
|
{
|
||||||
|
Group * pgroup = GetGroup(name);
|
||||||
|
|
||||||
|
if( !pgroup )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return pgroup->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Groups::Iterator Groups::Begin()
|
||||||
|
{
|
||||||
|
return table.Begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Groups::Iterator Groups::End()
|
||||||
|
{
|
||||||
|
return table.End();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Groups::SizeType Groups::Size()
|
||||||
|
{
|
||||||
|
return table.Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Groups::Remove(long group_id)
|
||||||
|
{
|
||||||
|
return table.Remove(group_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_groups
|
||||||
|
#define headerfile_winix_core_groups
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "models/group.h"
|
||||||
|
#include "ugcontainer.h"
|
||||||
|
#include "winixmodeldeprecated.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Groups : public WinixModelDeprecated
|
||||||
|
{
|
||||||
|
typedef UGContainer<Group> Table;
|
||||||
|
|
||||||
|
Table table;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void set_dependency(WinixModelDeprecated * winix_model);
|
||||||
|
|
||||||
|
typedef Table::Iterator Iterator;
|
||||||
|
typedef Table::SizeType SizeType;
|
||||||
|
|
||||||
|
Groups();
|
||||||
|
void Clear();
|
||||||
|
void ReadGroups();
|
||||||
|
Group * GetGroup(long group_id);
|
||||||
|
Group * GetGroup(const std::wstring & name);
|
||||||
|
long GetGroupId(const std::wstring & name);
|
||||||
|
Iterator Begin();
|
||||||
|
Iterator End();
|
||||||
|
SizeType Size();
|
||||||
|
bool Remove(long group_id);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "header.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
const wchar_t * Header::find_status_string_value(int http_status)
|
||||||
|
{
|
||||||
|
size_t table_len = sizeof(status_int_string_map) / sizeof(StatusIntStringMapHelper);
|
||||||
|
|
||||||
|
for(size_t i=0 ; i < table_len ; ++i)
|
||||||
|
{
|
||||||
|
if( status_int_string_map[i].status_int == http_status )
|
||||||
|
{
|
||||||
|
return status_int_string_map[i].status_str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Header::prepare_status_value(int http_status, pt::WTextStream & value, bool clear_value)
|
||||||
|
{
|
||||||
|
if( clear_value )
|
||||||
|
value.clear();
|
||||||
|
|
||||||
|
value << http_status;
|
||||||
|
const wchar_t * value_str = find_status_string_value(http_status);
|
||||||
|
|
||||||
|
if( value_str )
|
||||||
|
{
|
||||||
|
value << ' ' << value_str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Header::is_header_value_char_correct(wchar_t c)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* make sure to not allow at least \r or \r
|
||||||
|
*/
|
||||||
|
return c > 32 && c < 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Header::is_header_value_correct(const wchar_t * str)
|
||||||
|
{
|
||||||
|
for( ; *str ; ++str)
|
||||||
|
{
|
||||||
|
if( !is_header_value_char_correct(*str) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Header::is_header_value_correct(const std::wstring & str)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* dont use is_header_value_correct(str.c_str()) as there can be a null character (0) inside the string
|
||||||
|
*/
|
||||||
|
for(size_t i=0 ; i < str.size() ; ++i)
|
||||||
|
{
|
||||||
|
if( !is_header_value_char_correct(str[i]) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_header
|
||||||
|
#define headerfile_winix_core_header
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
#include <textstream/textstream.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
class Header
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* headers' names
|
||||||
|
*/
|
||||||
|
static constexpr const wchar_t * content_type = L"Content-Type";
|
||||||
|
static constexpr const wchar_t * accept = L"Accept";
|
||||||
|
static constexpr const wchar_t * accept_language = L"Accept-Language";
|
||||||
|
static constexpr const wchar_t * authorization = L"Authorization";
|
||||||
|
static constexpr const wchar_t * allow = L"Allow";
|
||||||
|
static constexpr const wchar_t * very = L"Very";
|
||||||
|
static constexpr const wchar_t * origin = L"Origin";
|
||||||
|
static constexpr const wchar_t * access_control_allow_methods = L"Access-Control-Allow-Methods";
|
||||||
|
static constexpr const wchar_t * access_control_allow_origin = L"Access-Control-Allow-Origin";
|
||||||
|
static constexpr const wchar_t * access_control_allow_headers = L"Access-Control-Allow-Headers";
|
||||||
|
static constexpr const wchar_t * access_control_allow_credentials = L"Access-Control-Allow-Credentials";
|
||||||
|
static constexpr const wchar_t * access_control_expose_headers = L"Access-Control-Expose-Headers";
|
||||||
|
static constexpr const wchar_t * access_control_max_age = L"Access-Control-Max-Age";
|
||||||
|
|
||||||
|
static constexpr const wchar_t * hx_location = L"HX-Location";
|
||||||
|
static constexpr const wchar_t * hx_push_url = L"HX-Push-Url";
|
||||||
|
static constexpr const wchar_t * hx_redirect = L"HX-Redirect";
|
||||||
|
static constexpr const wchar_t * hx_refresh = L"HX-Refresh";
|
||||||
|
static constexpr const wchar_t * hx_replace_url = L"HX-Replace-Url";
|
||||||
|
static constexpr const wchar_t * hx_reswap = L"HX-Reswap";
|
||||||
|
static constexpr const wchar_t * hx_retarget = L"HX-Retarget";
|
||||||
|
static constexpr const wchar_t * hx_reselect = L"HX-Reselect";
|
||||||
|
static constexpr const wchar_t * hx_trigger = L"HX-Trigger";
|
||||||
|
static constexpr const wchar_t * hx_trigger_after_settle = L"HX-Trigger-After-Settle";
|
||||||
|
static constexpr const wchar_t * hx_trigger_after_swap = L"HX-Trigger-After-Swap";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* headers' names lower case
|
||||||
|
*/
|
||||||
|
static constexpr const wchar_t * content_type_lc = L"content-type";
|
||||||
|
static constexpr const wchar_t * accept_lc = L"accept";
|
||||||
|
static constexpr const wchar_t * accept_language_lc = L"accept-language";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* headers' values
|
||||||
|
*/
|
||||||
|
static constexpr const wchar_t * application_octet_stream = L"application/octet-stream";
|
||||||
|
|
||||||
|
static constexpr const wchar_t * text_html = L"text/html";
|
||||||
|
static constexpr const wchar_t * application_json = L"application/json";
|
||||||
|
static constexpr const wchar_t * application_xml = L"application/xml";
|
||||||
|
static constexpr const wchar_t * application_xhtml_xml = L"application/xhtml+xml";
|
||||||
|
static constexpr const wchar_t * text_csv = L"text/csv";
|
||||||
|
static constexpr const wchar_t * text_javascript = L"text/javascript";
|
||||||
|
static constexpr const wchar_t * text_xml = L"text/xml";
|
||||||
|
|
||||||
|
static constexpr const wchar_t * all_all = L"*/*";
|
||||||
|
static constexpr const wchar_t * text_all = L"text/*";
|
||||||
|
static constexpr const wchar_t * application_all = L"application/*";
|
||||||
|
|
||||||
|
static constexpr const wchar_t * text_html_utf8 = L"text/html; charset=UTF-8";
|
||||||
|
static constexpr const wchar_t * application_json_utf8 = L"application/json; charset=UTF-8";
|
||||||
|
static constexpr const wchar_t * application_xml_utf8 = L"application/xml; charset=UTF-8";
|
||||||
|
static constexpr const wchar_t * application_xhtml_xml_utf8 = L"application/xhtml+xml; charset=UTF-8";
|
||||||
|
static constexpr const wchar_t * text_csv_utf8 = L"text/csv; charset=UTF-8";
|
||||||
|
static constexpr const wchar_t * text_javascript_utf8 = L"text/javascript; charset=UTF-8";
|
||||||
|
static constexpr const wchar_t * text_xml_utf8 = L"text/xml; charset=UTF-8";
|
||||||
|
|
||||||
|
static constexpr const wchar_t * application_x_www_form_urlencoded = L"application/x-www-form-urlencoded";
|
||||||
|
static constexpr const wchar_t * multipart_form_data = L"multipart/form-data";
|
||||||
|
|
||||||
|
static constexpr const wchar_t * bearer = L"Bearer";
|
||||||
|
static constexpr const wchar_t * winix = L"Winix";
|
||||||
|
|
||||||
|
|
||||||
|
static const int status_200_ok = 200;
|
||||||
|
static const int status_201_created = 201;
|
||||||
|
static const int status_204_no_content = 204;
|
||||||
|
static const int status_300_multiple_choices = 300;
|
||||||
|
static const int status_301_moved_permanently = 301;
|
||||||
|
static const int status_302_found = 302;
|
||||||
|
static const int status_303_see_other = 303;
|
||||||
|
static const int status_307_temporary_redirect = 307;
|
||||||
|
static const int status_400_bad_request = 400;
|
||||||
|
static const int status_403_forbidden = 403;
|
||||||
|
static const int status_404_not_found = 404;
|
||||||
|
static const int status_414_uri_too_long = 414;
|
||||||
|
static const int status_422_unprocessable_entity = 422;
|
||||||
|
static const int status_500_internal_server_error = 500;
|
||||||
|
static const int status_503_service_unavailable = 503;
|
||||||
|
|
||||||
|
|
||||||
|
static constexpr const wchar_t * str_status_200 = L"OK";
|
||||||
|
static constexpr const wchar_t * str_status_201 = L"Created";
|
||||||
|
static constexpr const wchar_t * str_status_204 = L"No Content";
|
||||||
|
static constexpr const wchar_t * str_status_300 = L"Multiple Choices";
|
||||||
|
static constexpr const wchar_t * str_status_301 = L"Moved Permanently";
|
||||||
|
static constexpr const wchar_t * str_status_302 = L"Found";
|
||||||
|
static constexpr const wchar_t * str_status_303 = L"See Other";
|
||||||
|
static constexpr const wchar_t * str_status_307 = L"Temporary Redirect";
|
||||||
|
static constexpr const wchar_t * str_status_400 = L"Bad Request";
|
||||||
|
static constexpr const wchar_t * str_status_403 = L"Forbidden";
|
||||||
|
static constexpr const wchar_t * str_status_404 = L"Not Found";
|
||||||
|
static constexpr const wchar_t * str_status_414 = L"URI Too Long";
|
||||||
|
static constexpr const wchar_t * str_status_422 = L"Unprocessable Entity";
|
||||||
|
static constexpr const wchar_t * str_status_500 = L"Internal Server Error";
|
||||||
|
static constexpr const wchar_t * str_status_503 = L"Service Unavailable";
|
||||||
|
|
||||||
|
|
||||||
|
static const wchar_t * find_status_string_value(int http_status);
|
||||||
|
static void prepare_status_value(int http_status, pt::WTextStream & value, bool clear_value = true);
|
||||||
|
|
||||||
|
static bool is_header_value_char_correct(wchar_t c);
|
||||||
|
static bool is_header_value_correct(const wchar_t * str);
|
||||||
|
static bool is_header_value_correct(const std::wstring & str);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
struct StatusIntStringMapHelper
|
||||||
|
{
|
||||||
|
int status_int;
|
||||||
|
const wchar_t * status_str;
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr StatusIntStringMapHelper status_int_string_map[] = {
|
||||||
|
{status_200_ok, str_status_200},
|
||||||
|
{status_201_created, str_status_201},
|
||||||
|
{status_204_no_content, str_status_204},
|
||||||
|
{status_300_multiple_choices, str_status_300},
|
||||||
|
{status_301_moved_permanently, str_status_301},
|
||||||
|
{status_302_found, str_status_302},
|
||||||
|
{status_303_see_other, str_status_303},
|
||||||
|
{status_307_temporary_redirect, str_status_307},
|
||||||
|
{status_400_bad_request, str_status_400},
|
||||||
|
{status_403_forbidden, str_status_403},
|
||||||
|
{status_404_not_found, str_status_404},
|
||||||
|
{status_414_uri_too_long, str_status_414},
|
||||||
|
{status_422_unprocessable_entity, str_status_422},
|
||||||
|
{status_500_internal_server_error, str_status_500},
|
||||||
|
{status_503_service_unavailable, str_status_503},
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class HeaderValue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
std::wstring value;
|
||||||
|
double weight; // q parameter in some headers
|
||||||
|
|
||||||
|
|
||||||
|
HeaderValue()
|
||||||
|
{
|
||||||
|
weight = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void log_values(const std::vector<HeaderValue> & header_values, Log & log)
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
bool is_first = true;
|
||||||
|
|
||||||
|
for(const HeaderValue & h: header_values)
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf)/sizeof(char), "%.3f", h.weight);
|
||||||
|
|
||||||
|
if( !is_first )
|
||||||
|
log << ", ";
|
||||||
|
|
||||||
|
log << h.value << ";q=" << buf;
|
||||||
|
is_first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,273 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2021, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "httpsimpleparser.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "utf8/utf8.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void HttpSimpleParser::ToLower(std::wstring & s)
|
||||||
|
{
|
||||||
|
for(wchar_t & c : s)
|
||||||
|
{
|
||||||
|
if( c>='A' && c<='Z' )
|
||||||
|
c = c - 'A' + 'a';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool HttpSimpleParser::IsWhite(int c)
|
||||||
|
{
|
||||||
|
if( c==' ' || c=='\t' )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HttpSimpleParser::SkipWhiteChars()
|
||||||
|
{
|
||||||
|
while( IsWhite(last_c) )
|
||||||
|
last_c = GetChar();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int HttpSimpleParser::ParseHalfHex(int c)
|
||||||
|
{
|
||||||
|
if( c>='a' && c<='z' )
|
||||||
|
c += 'A' - 'a'; // to upper case
|
||||||
|
|
||||||
|
|
||||||
|
if( c >= 'A' )
|
||||||
|
c = c - 'A' + 10;
|
||||||
|
else
|
||||||
|
c = c - '0';
|
||||||
|
|
||||||
|
c &= 0xf;
|
||||||
|
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void HttpSimpleParser::CheckSpecialChar()
|
||||||
|
{
|
||||||
|
if( last_c == '%' )
|
||||||
|
{
|
||||||
|
int c1 = GetChar();
|
||||||
|
int c2 = GetChar();
|
||||||
|
|
||||||
|
if( c1==-1 || c2==-1 )
|
||||||
|
{
|
||||||
|
last_c = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c1 = ParseHalfHex(c1);
|
||||||
|
c2 = ParseHalfHex(c2);
|
||||||
|
|
||||||
|
last_c = (c1 << 4) + c2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( last_c == '+' )
|
||||||
|
{
|
||||||
|
last_c = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void HttpSimpleParser::ReadName()
|
||||||
|
{
|
||||||
|
// we're checking 'separator' and '=' because the string is allowed not having '=' (the value is optional)
|
||||||
|
|
||||||
|
utf8_token.clear();
|
||||||
|
last_name.clear();
|
||||||
|
|
||||||
|
for( ; last_c!=-1 && last_c!=separator && last_c!='=' ; last_c = GetChar() )
|
||||||
|
{
|
||||||
|
if( recognize_special_chars )
|
||||||
|
CheckSpecialChar();
|
||||||
|
|
||||||
|
if( last_c != -1 )
|
||||||
|
{
|
||||||
|
if( getchar_returns_utf8_chars )
|
||||||
|
utf8_token += last_c;
|
||||||
|
else
|
||||||
|
last_name += last_c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getchar_returns_utf8_chars )
|
||||||
|
pt::utf8_to_wide(utf8_token, last_name);
|
||||||
|
|
||||||
|
if( last_c == '=' )
|
||||||
|
last_c = GetChar();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void HttpSimpleParser::ReadQuotedValue()
|
||||||
|
{
|
||||||
|
// skipping '"'
|
||||||
|
last_c = GetChar();
|
||||||
|
utf8_token.clear();
|
||||||
|
last_value.clear();
|
||||||
|
|
||||||
|
for( ; last_c!=-1 && last_c!='"' ; last_c = GetChar() )
|
||||||
|
{
|
||||||
|
if( recognize_special_chars )
|
||||||
|
CheckSpecialChar();
|
||||||
|
|
||||||
|
if( last_c != -1 )
|
||||||
|
{
|
||||||
|
if( getchar_returns_utf8_chars )
|
||||||
|
utf8_token += last_c;
|
||||||
|
else
|
||||||
|
last_value += last_c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getchar_returns_utf8_chars )
|
||||||
|
pt::utf8_to_wide(utf8_token, last_value);
|
||||||
|
|
||||||
|
if( last_c == '"' )
|
||||||
|
last_c = GetChar();
|
||||||
|
|
||||||
|
// looking for a separator (skipping)
|
||||||
|
for( ; last_c!=-1 && last_c!=separator ; last_c = GetChar() );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HttpSimpleParser::ReadNormalValue()
|
||||||
|
{
|
||||||
|
utf8_token.clear();
|
||||||
|
last_value.clear();
|
||||||
|
|
||||||
|
for( ; last_c!=-1 && last_c!=separator ; last_c = GetChar() )
|
||||||
|
{
|
||||||
|
if( recognize_special_chars )
|
||||||
|
CheckSpecialChar();
|
||||||
|
|
||||||
|
if( last_c != -1 )
|
||||||
|
{
|
||||||
|
if( getchar_returns_utf8_chars )
|
||||||
|
utf8_token += last_c;
|
||||||
|
else
|
||||||
|
last_value += last_c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getchar_returns_utf8_chars )
|
||||||
|
pt::utf8_to_wide(utf8_token, last_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HttpSimpleParser::ReadValue()
|
||||||
|
{
|
||||||
|
if( skip_white_chars )
|
||||||
|
SkipWhiteChars();
|
||||||
|
|
||||||
|
if( value_can_be_quoted && last_c == '"' )
|
||||||
|
ReadQuotedValue();
|
||||||
|
else
|
||||||
|
ReadNormalValue();
|
||||||
|
|
||||||
|
|
||||||
|
if( last_c == separator )
|
||||||
|
last_c = GetChar();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* there can be some important values like passwords so its better
|
||||||
|
* to clear them now
|
||||||
|
*/
|
||||||
|
void HttpSimpleParser::Clear()
|
||||||
|
{
|
||||||
|
Overwrite(last_name);
|
||||||
|
Overwrite(last_value);
|
||||||
|
Overwrite(utf8_token);
|
||||||
|
last_name.clear();
|
||||||
|
last_value.clear();
|
||||||
|
utf8_token.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HttpSimpleParser::Parse()
|
||||||
|
{
|
||||||
|
for( last_c = GetChar() ; last_c != -1 ; )
|
||||||
|
{
|
||||||
|
last_name.clear();
|
||||||
|
last_value.clear();
|
||||||
|
|
||||||
|
if( read_name )
|
||||||
|
ReadName();
|
||||||
|
|
||||||
|
ReadValue();
|
||||||
|
|
||||||
|
if( skip_white_chars )
|
||||||
|
{
|
||||||
|
TrimWhite(last_name);
|
||||||
|
TrimWhite(last_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Parameter(last_name, last_value); // user definied function
|
||||||
|
}
|
||||||
|
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2018, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_httpsimpleparser
|
||||||
|
#define headerfile_winix_core_httpsimpleparser
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "winixmodeldeprecated.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class HttpSimpleParser : public WinixModelDeprecated
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool read_name;
|
||||||
|
bool value_can_be_quoted;
|
||||||
|
bool skip_white_chars;
|
||||||
|
bool recognize_special_chars;
|
||||||
|
|
||||||
|
// if false then GetChar() returns wide characters (converted to int)
|
||||||
|
// if true then GetChar() returns utf8 characters (we have to convert them from utf8 to wide chars)
|
||||||
|
bool getchar_returns_utf8_chars;
|
||||||
|
|
||||||
|
int ParseHalfHex(int c);
|
||||||
|
void ReadName();
|
||||||
|
void ReadQuotedValue();
|
||||||
|
void ReadNormalValue();
|
||||||
|
void ReadValue();
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
std::wstring last_name;
|
||||||
|
std::wstring last_value;
|
||||||
|
std::string utf8_token;
|
||||||
|
|
||||||
|
int last_c;
|
||||||
|
int separator;
|
||||||
|
|
||||||
|
// '-1' means end (eof)
|
||||||
|
// when there is an eof this method can be called more than once (it should always return -1 in such a case)
|
||||||
|
virtual int GetChar() = 0;
|
||||||
|
virtual void Parameter(std::wstring & last_name, std::wstring & last_value) = 0;
|
||||||
|
|
||||||
|
void ToLower(std::wstring & s);
|
||||||
|
bool IsWhite(int c);
|
||||||
|
|
||||||
|
void SkipWhiteChars();
|
||||||
|
void CheckSpecialChar();
|
||||||
|
|
||||||
|
void Parse();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
HttpSimpleParser()
|
||||||
|
{
|
||||||
|
separator = '&';
|
||||||
|
read_name = true;
|
||||||
|
value_can_be_quoted = false;
|
||||||
|
skip_white_chars = false;
|
||||||
|
recognize_special_chars = true;
|
||||||
|
getchar_returns_utf8_chars = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,636 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
#include "image.h"
|
||||||
|
#include "core/misc.h"
|
||||||
|
#include "utf8/utf8.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "lock.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
void Image::SetConfig(Config * pconfig)
|
||||||
|
{
|
||||||
|
config = pconfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Image::SetSystem(System * psystem)
|
||||||
|
{
|
||||||
|
system = psystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// first thread (objects locked)
|
||||||
|
Image::Scale Image::GetImageScale(long dir_id)
|
||||||
|
{
|
||||||
|
Scale scale;
|
||||||
|
|
||||||
|
Mount * m = system->mounts.CalcMount(dir_id);
|
||||||
|
scale.cx = config->image_cx;
|
||||||
|
scale.cy = config->image_cy;
|
||||||
|
scale.aspect_mode = config->image_mode;
|
||||||
|
scale.quality = config->image_quality;
|
||||||
|
|
||||||
|
// reading width and height from the mount point (if exists)
|
||||||
|
int index = system->mounts.MountParImageSize();
|
||||||
|
|
||||||
|
if( m && m->param[index].defined && m->param[index].arg.size() == 2 )
|
||||||
|
{
|
||||||
|
scale.cx = Tol(m->param[index].arg[0]);
|
||||||
|
scale.cy = Tol(m->param[index].arg[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reading image mode from the mount point (if exists)
|
||||||
|
index = system->mounts.MountParImageMode();
|
||||||
|
|
||||||
|
if( m && m->param[index].defined && m->param[index].arg.size() == 1 )
|
||||||
|
scale.aspect_mode = Toi(m->param[index].arg[0]);
|
||||||
|
|
||||||
|
// reading image quality from the mount point (if exists)
|
||||||
|
index = system->mounts.MountParImageQuality();
|
||||||
|
|
||||||
|
if( m && m->param[index].defined && m->param[index].arg.size() == 1 )
|
||||||
|
scale.quality = Toi(m->param[index].arg[0]);
|
||||||
|
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// first thread (objects locked)
|
||||||
|
Image::Scale Image::GetThumbScale(long dir_id)
|
||||||
|
{
|
||||||
|
Scale scale;
|
||||||
|
|
||||||
|
Mount * m = system->mounts.CalcMount(dir_id);
|
||||||
|
scale.cx = config->thumb_cx;
|
||||||
|
scale.cy = config->thumb_cy;
|
||||||
|
scale.aspect_mode = config->thumb_mode;
|
||||||
|
scale.quality = config->thumb_quality;
|
||||||
|
|
||||||
|
// reading width and height from the mount point (if exists)
|
||||||
|
int index = system->mounts.MountParThumbSize();
|
||||||
|
|
||||||
|
if( m && m->param[index].defined && m->param[index].arg.size() == 2 )
|
||||||
|
{
|
||||||
|
scale.cx = Tol(m->param[index].arg[0]);
|
||||||
|
scale.cy = Tol(m->param[index].arg[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reading thumb mode from the mount point (if exists)
|
||||||
|
index = system->mounts.MountParThumbMode();
|
||||||
|
|
||||||
|
if( m && m->param[index].defined && m->param[index].arg.size() == 1 )
|
||||||
|
scale.aspect_mode = Toi(m->param[index].arg[0]);
|
||||||
|
|
||||||
|
// reading image quality from the mount point (if exists)
|
||||||
|
index = system->mounts.MountParThumbQuality();
|
||||||
|
|
||||||
|
if( m && m->param[index].defined && m->param[index].arg.size() == 1 )
|
||||||
|
scale.quality = Toi(m->param[index].arg[0]);
|
||||||
|
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// first thread (objects locked)
|
||||||
|
void Image::Resize(long file_id, size_t cx, size_t cy, int aspect_mode, int quality)
|
||||||
|
{
|
||||||
|
item_temp.type = WINIX_IMAGE_TYPE_RESIZE;
|
||||||
|
item_temp.file_id = file_id;
|
||||||
|
item_temp.cx = cx;
|
||||||
|
item_temp.cy = cy;
|
||||||
|
item_temp.aspect_mode = aspect_mode;
|
||||||
|
item_temp.quality = quality;
|
||||||
|
|
||||||
|
CheckParam(item_temp);
|
||||||
|
image_tab.insert(image_tab.end(), item_temp);
|
||||||
|
WakeUpThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// first thread (objects locked)
|
||||||
|
void Image::CreateThumb(long file_id, size_t thumb_cx, size_t thumb_cy, int aspect_mode, int quality)
|
||||||
|
{
|
||||||
|
item_temp.type = WINIX_IMAGE_TYPE_CREATE_THUMB;
|
||||||
|
item_temp.file_id = file_id;
|
||||||
|
item_temp.thumb_cx = thumb_cx;
|
||||||
|
item_temp.thumb_cy = thumb_cy;
|
||||||
|
item_temp.aspect_mode = aspect_mode;
|
||||||
|
item_temp.quality = quality;
|
||||||
|
|
||||||
|
CheckParam(item_temp);
|
||||||
|
image_tab.insert(image_tab.end(), item_temp);
|
||||||
|
WakeUpThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// first thread (objects locked)
|
||||||
|
void Image::Crop(long file_id, size_t xoffset, size_t yoffset, size_t cx, size_t cy, int quality)
|
||||||
|
{
|
||||||
|
item_temp.type = WINIX_IMAGE_TYPE_CROP;
|
||||||
|
item_temp.file_id = file_id;
|
||||||
|
item_temp.xoffset = xoffset;
|
||||||
|
item_temp.yoffset = yoffset;
|
||||||
|
item_temp.cx = cx;
|
||||||
|
item_temp.cy = cy;
|
||||||
|
item_temp.quality = quality;
|
||||||
|
|
||||||
|
CheckParam(item_temp);
|
||||||
|
image_tab.insert(image_tab.end(), item_temp);
|
||||||
|
WakeUpThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// first thread (objects locked)
|
||||||
|
void Image::CropThumb(long file_id, size_t xoffset, size_t yoffset, size_t cx, size_t cy, int quality)
|
||||||
|
{
|
||||||
|
item_temp.type = WINIX_IMAGE_TYPE_CROP_THUMB;
|
||||||
|
item_temp.file_id = file_id;
|
||||||
|
item_temp.xoffset = xoffset;
|
||||||
|
item_temp.yoffset = yoffset;
|
||||||
|
item_temp.cx = cx;
|
||||||
|
item_temp.cy = cy;
|
||||||
|
item_temp.quality = quality;
|
||||||
|
|
||||||
|
CheckParam(item_temp);
|
||||||
|
image_tab.insert(image_tab.end(), item_temp);
|
||||||
|
WakeUpThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// first thread (objects locked)
|
||||||
|
void Image::CropNewThumb(long file_id, size_t xoffset, size_t yoffset, size_t cx, size_t cy,
|
||||||
|
size_t thumb_cx, size_t thumb_cy, int aspect_mode, int quality)
|
||||||
|
{
|
||||||
|
item_temp.type = WINIX_IMAGE_TYPE_CREATE_CROP_NEW_THUMB;
|
||||||
|
item_temp.file_id = file_id;
|
||||||
|
item_temp.xoffset = xoffset;
|
||||||
|
item_temp.yoffset = yoffset;
|
||||||
|
item_temp.cx = cx;
|
||||||
|
item_temp.cy = cy;
|
||||||
|
item_temp.thumb_cx = thumb_cx;
|
||||||
|
item_temp.thumb_cy = thumb_cy;
|
||||||
|
item_temp.aspect_mode = aspect_mode;
|
||||||
|
item_temp.quality = quality;
|
||||||
|
|
||||||
|
CheckParam(item_temp);
|
||||||
|
image_tab.insert(image_tab.end(), item_temp);
|
||||||
|
WakeUpThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Image::CheckParam(ImageItem & item)
|
||||||
|
{
|
||||||
|
SetMinMax(item.aspect_mode, 1, 7);
|
||||||
|
SetMinMax(item.quality, 0, 100);
|
||||||
|
SetMinMax(item.cx, 1, 30000);
|
||||||
|
SetMinMax(item.cy, 1, 30000);
|
||||||
|
SetMinMax(item.thumb_cx, 1, 30000);
|
||||||
|
SetMinMax(item.thumb_cy, 1, 30000);
|
||||||
|
SetMinMax(item.xoffset, 0, 30000);
|
||||||
|
SetMinMax(item.yoffset, 0, 30000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects locked)
|
||||||
|
bool Image::SignalReceived()
|
||||||
|
{
|
||||||
|
return !image_tab.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects not locked)
|
||||||
|
void Image::Do()
|
||||||
|
{
|
||||||
|
ImageTab::iterator i;
|
||||||
|
bool end;
|
||||||
|
|
||||||
|
Lock();
|
||||||
|
i = image_tab.begin();
|
||||||
|
Unlock();
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Winix::Lock lock_object(synchro);
|
||||||
|
|
||||||
|
if( i != image_tab.end() )
|
||||||
|
{
|
||||||
|
item_work = *i;
|
||||||
|
image_tab.erase(i++);
|
||||||
|
end = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
end = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock_object.Unlock();
|
||||||
|
|
||||||
|
if( !end )
|
||||||
|
CreateImage();
|
||||||
|
|
||||||
|
}
|
||||||
|
while( !end && !IsExitSignal() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Image::EscapePath(const std::string & path, pt::TextStream & out, bool clear_stream)
|
||||||
|
{
|
||||||
|
if( clear_stream )
|
||||||
|
out.clear();
|
||||||
|
|
||||||
|
out << '"';
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<path.size() ; ++i)
|
||||||
|
{
|
||||||
|
if( path[i] == '"' )
|
||||||
|
out << '\\';
|
||||||
|
|
||||||
|
if( path[i] != 0 )
|
||||||
|
out << path[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
out << '\"';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
from: http://www.imagemagick.org/script/command-line-processing.php#geometry
|
||||||
|
|
||||||
|
scale% Height and width both scaled by specified percentage.
|
||||||
|
scale-x%xscale-y% Height and width individually scaled by specified percentages. (Only one % symbol needed.)
|
||||||
|
width Width given, height automagically selected to preserve aspect ratio.
|
||||||
|
xheight Height given, width automagically selected to preserve aspect ratio.
|
||||||
|
widthxheight Maximum values of height and width given, aspect ratio preserved.
|
||||||
|
widthxheight^ Minimum values of width and height given, aspect ratio preserved.
|
||||||
|
widthxheight! Width and height emphatically given, original aspect ratio ignored.
|
||||||
|
widthxheight> Change as per widthxheight but only if an image dimension exceeds a specified dimension.
|
||||||
|
widthxheight< Change dimensions only if both image dimensions exceed specified dimensions.
|
||||||
|
*/
|
||||||
|
void Image::SelectAspect(size_t cx, size_t cy)
|
||||||
|
{
|
||||||
|
switch( item_work.aspect_mode )
|
||||||
|
{
|
||||||
|
case WINIX_IMAGE_MODE_1:
|
||||||
|
command << cx;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINIX_IMAGE_MODE_3:
|
||||||
|
command << cx << "x" << cy;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINIX_IMAGE_MODE_4:
|
||||||
|
command << '"' << cx << "x" << cy << "^\"";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINIX_IMAGE_MODE_5:
|
||||||
|
command << '"' << cx << "x" << cy << "!\"";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINIX_IMAGE_MODE_6:
|
||||||
|
command << '"' << cx << "x" << cy << ">\"";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINIX_IMAGE_MODE_7:
|
||||||
|
command << '"' << cx << "x" << cy << "<\"";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINIX_IMAGE_MODE_2:
|
||||||
|
default:
|
||||||
|
command << "x" << cy;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects locked)
|
||||||
|
bool Image::CreateInputFileName()
|
||||||
|
{
|
||||||
|
bool thumb = (item_work.type == WINIX_IMAGE_TYPE_CROP_THUMB);
|
||||||
|
|
||||||
|
if( thumb && !file_work.item_content.file_has_thumb )
|
||||||
|
{
|
||||||
|
log << log1 << "Image: file id: " << file_work.id << ", url: " << file_work.url
|
||||||
|
<< " doesn't have a thumbnail yet (skipping)" << logend;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( system->MakeFilePath(file_work, src_path, thumb) )
|
||||||
|
{
|
||||||
|
pt::wide_to_utf8(src_path, input_file_name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log << log1 << "Image: cannot create a source path" << logend;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects locked)
|
||||||
|
void Image::CreateTmpFileName()
|
||||||
|
{
|
||||||
|
stream_tmp_path.clear();
|
||||||
|
stream_tmp_path << config->upload_dir << L"/tmp/image_" << std::time(0);
|
||||||
|
stream_tmp_path.to_str(tmp_file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects are not locked)
|
||||||
|
bool Image::CreateCommand()
|
||||||
|
{
|
||||||
|
Winix::Lock lock_object(synchro);
|
||||||
|
|
||||||
|
// iq.SetAll(true, false);
|
||||||
|
// iq.WhereId(item_work.file_id);
|
||||||
|
|
||||||
|
morm::Finder<Item> finder(model_connector);
|
||||||
|
file_work = finder.select().where().eq(L"id", item_work.file_id).get();
|
||||||
|
|
||||||
|
// the file could have been changed especially when there is a long queue of files
|
||||||
|
if( !file_work.found() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( !CreateInputFileName() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
command.clear();
|
||||||
|
command << config->convert_cmd;
|
||||||
|
|
||||||
|
command << " ";
|
||||||
|
EscapePath(input_file_name, command, false);
|
||||||
|
command << " -quiet -quality " << item_work.quality;
|
||||||
|
|
||||||
|
if( item_work.type == WINIX_IMAGE_TYPE_RESIZE )
|
||||||
|
{
|
||||||
|
command << " -resize ";
|
||||||
|
SelectAspect(item_work.cx, item_work.cy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( item_work.type == WINIX_IMAGE_TYPE_CREATE_THUMB )
|
||||||
|
{
|
||||||
|
command << " -strip -thumbnail ";
|
||||||
|
SelectAspect(item_work.thumb_cx, item_work.thumb_cy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( item_work.type == WINIX_IMAGE_TYPE_CROP )
|
||||||
|
{
|
||||||
|
command << " -crop " << item_work.cx << "x" << item_work.cy
|
||||||
|
<< "+" << item_work.xoffset << "+" << item_work.yoffset << " +repage ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( item_work.type == WINIX_IMAGE_TYPE_CROP_THUMB )
|
||||||
|
{
|
||||||
|
command << " -strip -crop " << item_work.cx << "x" << item_work.cy
|
||||||
|
<< "+" << item_work.xoffset << "+" << item_work.yoffset
|
||||||
|
<< " +repage ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( item_work.type == WINIX_IMAGE_TYPE_CREATE_CROP_NEW_THUMB )
|
||||||
|
{
|
||||||
|
command << " -strip -crop " << item_work.cx << "x" << item_work.cy
|
||||||
|
<< "+" << item_work.xoffset << "+" << item_work.yoffset
|
||||||
|
<< " +repage -thumbnail ";
|
||||||
|
SelectAspect(item_work.thumb_cx, item_work.thumb_cy);
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateTmpFileName();
|
||||||
|
|
||||||
|
command << " ";
|
||||||
|
EscapePath(tmp_file_name, command, false);
|
||||||
|
|
||||||
|
log << log4 << "Image: running: " << command << logend;
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects are locked)
|
||||||
|
void Image::ImageSavedCorrectly()
|
||||||
|
{
|
||||||
|
if( item_work.type == WINIX_IMAGE_TYPE_CREATE_THUMB )
|
||||||
|
{
|
||||||
|
if( !file_work.item_content.file_has_thumb )
|
||||||
|
{
|
||||||
|
file_work.item_content.file_has_thumb = true;
|
||||||
|
|
||||||
|
file_work.propagate_connector();
|
||||||
|
file_work.item_content.update(false);
|
||||||
|
//db->EditHasThumbById(true, file_work.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
log << log3 << "Image: generated a thumbnail: " << dst_path << logend;
|
||||||
|
plugin->Call(model_connector, &log, nullptr, WINIX_CREATED_THUMB, &file_work, nullptr, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( item_work.type == WINIX_IMAGE_TYPE_RESIZE )
|
||||||
|
{
|
||||||
|
log << log3 << "Image: image resized: " << dst_path << logend;
|
||||||
|
plugin->Call(model_connector, &log, nullptr, WINIX_IMAGE_RESIZED, &file_work, nullptr, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( item_work.type == WINIX_IMAGE_TYPE_CROP )
|
||||||
|
{
|
||||||
|
log << log3 << "Image: image cropped: " << dst_path << logend;
|
||||||
|
// !! IMPROVE ME add a correct message
|
||||||
|
//plugin->Call(model_connector, &log, nullptr, WINIX_IMAGE_RESIZED, &file_work, nullptr, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( item_work.type == WINIX_IMAGE_TYPE_CROP_THUMB )
|
||||||
|
{
|
||||||
|
log << log3 << "Image: image thumbnail cropped: " << dst_path << logend;
|
||||||
|
// !! IMPROVE ME add a correct message
|
||||||
|
//plugin->Call(model_connector, &log, nullptr, WINIX_IMAGE_RESIZED, &file_work, nullptr, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( item_work.type == WINIX_IMAGE_TYPE_CREATE_CROP_NEW_THUMB )
|
||||||
|
{
|
||||||
|
log << log3 << "Image: a new thumbnail from an original image was cropped: " << dst_path << logend;
|
||||||
|
// !! IMPROVE ME add a correct message
|
||||||
|
//plugin->Call((Session*)0, WINIX_IMAGE_RESIZED, &file_work);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects are not locked)
|
||||||
|
void Image::SaveImage()
|
||||||
|
{
|
||||||
|
Winix::Lock lock_object(synchro);
|
||||||
|
|
||||||
|
// the file could have been changed especially when creating the image lasted too long
|
||||||
|
//iq.SetAll(true, false);
|
||||||
|
//iq.WhereId(item_work.file_id);
|
||||||
|
|
||||||
|
morm::Finder<Item> finder(model_connector);
|
||||||
|
file_work = finder.select().where().eq(L"id", item_work.file_id).get();
|
||||||
|
|
||||||
|
|
||||||
|
// the file could have been changed especially when there is a long queue of files
|
||||||
|
if( !file_work.found() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
//if( db->GetItem(file_work, iq) == WINIX_ERR_OK )
|
||||||
|
//{
|
||||||
|
bool thumb = (item_work.type == WINIX_IMAGE_TYPE_CREATE_THUMB ||
|
||||||
|
item_work.type == WINIX_IMAGE_TYPE_CROP_THUMB ||
|
||||||
|
item_work.type == WINIX_IMAGE_TYPE_CREATE_CROP_NEW_THUMB );
|
||||||
|
|
||||||
|
if( system->MakeFilePath(file_work, dst_path, thumb, true, config->upload_dirs_chmod, config->upload_group_int) )
|
||||||
|
{
|
||||||
|
std::wstring from;
|
||||||
|
stream_tmp_path.to_str(from);
|
||||||
|
|
||||||
|
if( RenameFile(from, dst_path) )
|
||||||
|
{
|
||||||
|
// it doesn't matter for us if there is an error when chmod/chown on a file
|
||||||
|
// the admin (root) will correct it
|
||||||
|
SetPriv(dst_path, config->upload_files_chmod, config->upload_group_int);
|
||||||
|
ImageSavedCorrectly();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log << log1 << "Image: cannot move a temporary file: " << stream_tmp_path
|
||||||
|
<< ", to: " << dst_path << logend;
|
||||||
|
|
||||||
|
Winix::RemoveFile(from);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log << log1 << "Image: cannot create a destination path" << logend;
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects are not locked)
|
||||||
|
void Image::CreateImage()
|
||||||
|
{
|
||||||
|
if( CreateCommand() )
|
||||||
|
{
|
||||||
|
std::string command_str;
|
||||||
|
command.to_str(command_str);
|
||||||
|
int res = std::system(command_str.c_str());
|
||||||
|
|
||||||
|
if( res == 0 )
|
||||||
|
{
|
||||||
|
SaveImage();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log << log3 << "Image: some problems with creating an image"
|
||||||
|
<< ", 'convert' process returned: " << res << logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log << logsave;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects are not locked)
|
||||||
|
// !! there is a problem with GIF files
|
||||||
|
// Bus error (core dumped)
|
||||||
|
/*
|
||||||
|
#include "wand/MagickWand.h"
|
||||||
|
|
||||||
|
// compiler options:
|
||||||
|
// include: -I/usr/local/include/ImageMagick
|
||||||
|
// link with: `MagickWand-config --ldflags --libs`
|
||||||
|
|
||||||
|
void Image::CreateThumbnail()
|
||||||
|
{
|
||||||
|
pt::wide_to_utf8(item_work.source, sourcea);
|
||||||
|
pt::wide_to_utf8(item_work.dst, dsta);
|
||||||
|
|
||||||
|
MagickWandGenesis();
|
||||||
|
|
||||||
|
MagickWand * wand = NewMagickWand();
|
||||||
|
|
||||||
|
if( MagickReadImage(wand, sourcea.c_str()) )
|
||||||
|
{
|
||||||
|
MagickThumbnailImage(wand, item_work.cx, item_work.cy);
|
||||||
|
|
||||||
|
if( MagickWriteImage(wand, dsta.c_str()) )
|
||||||
|
{
|
||||||
|
Lock();
|
||||||
|
log << log3 << "Image: created a thumbnail: " << dsta << logend;
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DestroyMagickWand(wand);
|
||||||
|
|
||||||
|
MagickWandTerminus();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
@@ -0,0 +1,208 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_image
|
||||||
|
#define headerfile_winix_core_image
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
#include "basethread.h"
|
||||||
|
#include "core/config.h"
|
||||||
|
#include "models/item.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class System;
|
||||||
|
|
||||||
|
|
||||||
|
// aspect modes:
|
||||||
|
// Width given, height automagically selected to preserve aspect ratio.
|
||||||
|
#define WINIX_IMAGE_MODE_1 1
|
||||||
|
|
||||||
|
// Height given, width automagically selected to preserve aspect ratio.
|
||||||
|
#define WINIX_IMAGE_MODE_2 2
|
||||||
|
|
||||||
|
// Maximum values of height and width given, aspect ratio preserved.
|
||||||
|
#define WINIX_IMAGE_MODE_3 3
|
||||||
|
|
||||||
|
// Minimum values of width and height given, aspect ratio preserved.
|
||||||
|
#define WINIX_IMAGE_MODE_4 4
|
||||||
|
|
||||||
|
// Width and height emphatically given, original aspect ratio ignored.
|
||||||
|
#define WINIX_IMAGE_MODE_5 5
|
||||||
|
|
||||||
|
// Change as per widthxheight but only if an image dimension exceeds a specified dimension.
|
||||||
|
#define WINIX_IMAGE_MODE_6 6
|
||||||
|
|
||||||
|
// Change dimensions only if both image dimensions are less than specified dimensions.
|
||||||
|
#define WINIX_IMAGE_MODE_7 7
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// resizing
|
||||||
|
#define WINIX_IMAGE_TYPE_RESIZE 1
|
||||||
|
|
||||||
|
// generating a thumbnail
|
||||||
|
#define WINIX_IMAGE_TYPE_CREATE_THUMB 2
|
||||||
|
|
||||||
|
// cropping an image
|
||||||
|
#define WINIX_IMAGE_TYPE_CROP 3
|
||||||
|
|
||||||
|
// cropping an thumbnail
|
||||||
|
#define WINIX_IMAGE_TYPE_CROP_THUMB 4
|
||||||
|
|
||||||
|
// creating by cropping a new thumbnail (from an original image)
|
||||||
|
#define WINIX_IMAGE_TYPE_CREATE_CROP_NEW_THUMB 5
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
*/
|
||||||
|
class Image : public BaseThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct Scale
|
||||||
|
{
|
||||||
|
size_t cx;
|
||||||
|
size_t cy;
|
||||||
|
int aspect_mode;
|
||||||
|
int quality;
|
||||||
|
|
||||||
|
Scale()
|
||||||
|
{
|
||||||
|
cx = cy = 1;
|
||||||
|
aspect_mode = 2;
|
||||||
|
quality = 100;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void SetConfig(Config * pconfig);
|
||||||
|
void SetSystem(System * psystem);
|
||||||
|
|
||||||
|
|
||||||
|
// returning scale info for a directory
|
||||||
|
Scale GetImageScale(long dir_id);
|
||||||
|
|
||||||
|
// returning scale info (for thumbnails) for a directory
|
||||||
|
Scale GetThumbScale(long dir_id);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Resize(long file_id, size_t cx, size_t cy, int aspect_mode, int quality);
|
||||||
|
|
||||||
|
// creating a new thumbnail from an original image
|
||||||
|
void CreateThumb(long file_id, size_t thumb_cx, size_t thumb_cy, int aspect_mode, int quality);
|
||||||
|
|
||||||
|
// cropping an image (the thumbnail is not changed)
|
||||||
|
void Crop(long file_id, size_t xoffset, size_t yoffset, size_t cx, size_t cy, int quality);
|
||||||
|
|
||||||
|
// cropping an existing thumbnail
|
||||||
|
void CropThumb(long file_id, size_t xoffset, size_t yoffset, size_t cx, size_t cy, int quality);
|
||||||
|
|
||||||
|
// creating and cropping a new thumbnail (from an original image)
|
||||||
|
void CropNewThumb(long file_id, size_t xoffset, size_t yoffset, size_t cx, size_t cy,
|
||||||
|
size_t thumb_cx, size_t thumb_cy, int aspect_mode, int quality);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Config * config;
|
||||||
|
System * system;
|
||||||
|
|
||||||
|
struct ImageItem
|
||||||
|
{
|
||||||
|
int type; // WINIX_IMAGE_TYPE_*
|
||||||
|
long file_id;
|
||||||
|
size_t cx;
|
||||||
|
size_t cy;
|
||||||
|
size_t xoffset; // xoffset and yoffset are used when cropping
|
||||||
|
size_t yoffset;
|
||||||
|
size_t thumb_cx;
|
||||||
|
size_t thumb_cy;
|
||||||
|
int aspect_mode;
|
||||||
|
int quality;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename int_type>
|
||||||
|
void SetMinMax(int_type & var, int var_min, int var_max)
|
||||||
|
{
|
||||||
|
if( static_cast<int>(var) < var_min )
|
||||||
|
var = var_min;
|
||||||
|
|
||||||
|
if( static_cast<int>(var) > var_max )
|
||||||
|
var = var_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// queue of thumbnails to create
|
||||||
|
typedef std::list<ImageItem> ImageTab;
|
||||||
|
ImageTab image_tab;
|
||||||
|
ImageItem item_temp;
|
||||||
|
|
||||||
|
// only for second thread
|
||||||
|
ImageItem item_work;
|
||||||
|
std::wstring src_path, dst_path;
|
||||||
|
pt::TextStream command;
|
||||||
|
pt::WTextStream stream_tmp_path;
|
||||||
|
std::string input_file_name;
|
||||||
|
std::string tmp_file_name;
|
||||||
|
Item file_work;
|
||||||
|
|
||||||
|
virtual bool SignalReceived();
|
||||||
|
virtual void Do();
|
||||||
|
bool CreateCommand();
|
||||||
|
bool CreateInputFileName();
|
||||||
|
void CreateTmpFileName();
|
||||||
|
void SaveImage();
|
||||||
|
void CreateImage();
|
||||||
|
void SelectAspect(size_t cx, size_t cy);
|
||||||
|
void EscapePath(const std::string & path, pt::TextStream & out, bool clear_stream = true);
|
||||||
|
void CheckParam(ImageItem & item);
|
||||||
|
void ImageSavedCorrectly();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2014, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_ipban
|
||||||
|
#define headerfile_winix_core_ipban
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// telling if the IPBan record is active
|
||||||
|
// we have two records: active and non active
|
||||||
|
// non active records is something like a history
|
||||||
|
// it is used to remember the last ban level
|
||||||
|
// so based on this in the future a next greater ban can be calculated
|
||||||
|
#define WINIX_IPBAN_FLAG_ACTIVE 1
|
||||||
|
|
||||||
|
// current ban level
|
||||||
|
// (if one of these flag is set and the record is active then it means the IP is banned at the moment)
|
||||||
|
// level 1: banned for short time
|
||||||
|
// level 2: can be set after level 1 has expired and the attacker still have not given up
|
||||||
|
// banned for some longer time in level 1
|
||||||
|
// level 3: can be set after level 2
|
||||||
|
// banned for much more time
|
||||||
|
#define WINIX_IPBAN_FLAG_BAN_LEVEL1 2
|
||||||
|
#define WINIX_IPBAN_FLAG_BAN_LEVEL2 4
|
||||||
|
#define WINIX_IPBAN_FLAG_BAN_LEVEL3 8
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct defining some restrictions to an IP address
|
||||||
|
*/
|
||||||
|
struct IPBan
|
||||||
|
{
|
||||||
|
// at the moment only IPv4 are supported
|
||||||
|
int ip;
|
||||||
|
|
||||||
|
// one or more flags from WINIX_IPBAN_FLAG_*
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
// when this record was last used
|
||||||
|
time_t last_used;
|
||||||
|
|
||||||
|
// when the restrictions (ban) should be removed
|
||||||
|
// valid only if some of WINIX_IPBAN_FLAG_BAN_LEVELX flags are set
|
||||||
|
// actually we do not remove the record but unsets WINIX_IPBAN_FLAG_ACTIVE flag
|
||||||
|
// so in the future we can check whether we need to change
|
||||||
|
// the ban level to a greater value
|
||||||
|
time_t expires;
|
||||||
|
|
||||||
|
|
||||||
|
// how many incorrect login attempts there are
|
||||||
|
unsigned short int incorrect_login_events;
|
||||||
|
|
||||||
|
// how many incorrect encoded cookie were sent
|
||||||
|
// only used if config.session_cookie_encode is true and session_keys_file is defined
|
||||||
|
unsigned short int broken_encoded_cookie_events;
|
||||||
|
|
||||||
|
// how many incorrect session identifiers were sent
|
||||||
|
unsigned short int session_hijacking_events;
|
||||||
|
|
||||||
|
// client didn't send a session cookie
|
||||||
|
// it can be a bot or just someone wants to DOS the server
|
||||||
|
// (a new session will be create)
|
||||||
|
unsigned short int no_session_cookie_events;
|
||||||
|
|
||||||
|
|
||||||
|
bool HasFlag(int flag) const
|
||||||
|
{
|
||||||
|
return (flags & flag) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetFlag(int flag)
|
||||||
|
{
|
||||||
|
flags = flags | flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ClearFlag(int flag)
|
||||||
|
{
|
||||||
|
flags = flags & (~flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsIPBanned() const
|
||||||
|
{
|
||||||
|
if( !HasFlag(WINIX_IPBAN_FLAG_ACTIVE) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return HasFlag(WINIX_IPBAN_FLAG_BAN_LEVEL1) ||
|
||||||
|
HasFlag(WINIX_IPBAN_FLAG_BAN_LEVEL2) ||
|
||||||
|
HasFlag(WINIX_IPBAN_FLAG_BAN_LEVEL3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IncrementBanLevel(time_t level1_expires, time_t level2_expires, time_t level3_expires)
|
||||||
|
{
|
||||||
|
if( HasFlag(WINIX_IPBAN_FLAG_BAN_LEVEL3) )
|
||||||
|
{
|
||||||
|
expires = level3_expires;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( HasFlag(WINIX_IPBAN_FLAG_BAN_LEVEL2) )
|
||||||
|
{
|
||||||
|
SetFlag(WINIX_IPBAN_FLAG_BAN_LEVEL3);
|
||||||
|
expires = level3_expires;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( HasFlag(WINIX_IPBAN_FLAG_BAN_LEVEL1) )
|
||||||
|
{
|
||||||
|
SetFlag(WINIX_IPBAN_FLAG_BAN_LEVEL2);
|
||||||
|
expires = level2_expires;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetFlag(WINIX_IPBAN_FLAG_BAN_LEVEL1);
|
||||||
|
expires = level1_expires;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IPBan()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
ip = 0;
|
||||||
|
flags = 0;
|
||||||
|
last_used = 0;
|
||||||
|
expires = 0;
|
||||||
|
incorrect_login_events = 0;
|
||||||
|
broken_encoded_cookie_events = 0;
|
||||||
|
session_hijacking_events = 0;
|
||||||
|
no_session_cookie_events = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ResetEventsCounters()
|
||||||
|
{
|
||||||
|
ClearFlag(WINIX_IPBAN_FLAG_ACTIVE);
|
||||||
|
incorrect_login_events = 0;
|
||||||
|
broken_encoded_cookie_events = 0;
|
||||||
|
session_hijacking_events = 0;
|
||||||
|
no_session_cookie_events = 0;
|
||||||
|
expires = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2014, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include "ipbancontainer.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "date/date.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
IPBanContainer::IPBanContainer()
|
||||||
|
{
|
||||||
|
is_ipban_tab_sorted = true; // an empty list is sorted
|
||||||
|
soft_max_size = 100;
|
||||||
|
max_size = 110;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IPBanContainer::SetMaxSize(size_t soft_size, size_t size)
|
||||||
|
{
|
||||||
|
soft_max_size = soft_size;
|
||||||
|
max_size = size;
|
||||||
|
|
||||||
|
if( max_size < soft_max_size )
|
||||||
|
max_size = soft_max_size + 1;
|
||||||
|
|
||||||
|
ipban_tab.reserve(max_size);
|
||||||
|
sort_helper_tab.reserve(max_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// returning a reference to the added (or existed) record
|
||||||
|
IPBan & IPBanContainer::AddIP(int ip)
|
||||||
|
{
|
||||||
|
IPBan * old_ip_ban = FindIP(ip);
|
||||||
|
|
||||||
|
if( !old_ip_ban )
|
||||||
|
{
|
||||||
|
IPBan ip_ban;
|
||||||
|
ip_ban.ip = ip;
|
||||||
|
|
||||||
|
if( ipban_tab.size() >= max_size )
|
||||||
|
RemoveOldRecords();
|
||||||
|
|
||||||
|
ipban_tab.push_back(ip_ban);
|
||||||
|
is_ipban_tab_sorted = false;
|
||||||
|
return ipban_tab.back();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return *old_ip_ban;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IPBanContainer::RemoveIP(int ip)
|
||||||
|
{
|
||||||
|
IPBan * ipban = FindIP(ip);
|
||||||
|
|
||||||
|
if( ipban )
|
||||||
|
{
|
||||||
|
size_t index = ipban - &ipban_tab[0];
|
||||||
|
ipban_tab.erase(ipban_tab.begin() + index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IPBanContainer::IsSorted()
|
||||||
|
{
|
||||||
|
return is_ipban_tab_sorted;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IPBanContainer::Clear()
|
||||||
|
{
|
||||||
|
ipban_tab.clear();
|
||||||
|
is_ipban_tab_sorted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// we need to remove some old records for the size of the container
|
||||||
|
// to be less or equal to soft_max_size
|
||||||
|
void IPBanContainer::RemoveOldRecords()
|
||||||
|
{
|
||||||
|
size_t to_remove = 0;
|
||||||
|
|
||||||
|
if( ipban_tab.size() >= soft_max_size )
|
||||||
|
to_remove = ipban_tab.size() - soft_max_size;
|
||||||
|
|
||||||
|
if( to_remove > 0 )
|
||||||
|
{
|
||||||
|
sort_helper_tab.resize(ipban_tab.size());
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<ipban_tab.size() ; ++i)
|
||||||
|
sort_helper_tab[i] = i;
|
||||||
|
|
||||||
|
std::sort(sort_helper_tab.begin(), sort_helper_tab.end(), SortByLastUsedHelper(this));
|
||||||
|
sort_helper_tab.resize(to_remove);
|
||||||
|
std::sort(sort_helper_tab.begin(), sort_helper_tab.end());
|
||||||
|
|
||||||
|
while( to_remove-- > 0 )
|
||||||
|
ipban_tab.erase(ipban_tab.begin() + sort_helper_tab[to_remove]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// for debug purposes
|
||||||
|
void IPBanContainer::PrintTab()
|
||||||
|
{
|
||||||
|
log << log4 << "ipban_tab (size: " << ipban_tab.size() << ")" << logend;
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<ipban_tab.size() ; ++i)
|
||||||
|
{
|
||||||
|
log << log4 << i << ": ip: " << ipban_tab[i].ip << ", flags: " << ipban_tab[i].flags << ", last_used: ";
|
||||||
|
|
||||||
|
pt::Date date(ipban_tab[i].last_used);
|
||||||
|
log << date << ", expires: ";
|
||||||
|
|
||||||
|
date = ipban_tab[i].expires;
|
||||||
|
log << date << logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// for debug purposes
|
||||||
|
void IPBanContainer::PrintTab2()
|
||||||
|
{
|
||||||
|
log << log4 << "sort_helper_tab (size: " << sort_helper_tab.size() << ")" << logend;
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<sort_helper_tab.size() ; ++i)
|
||||||
|
{
|
||||||
|
IPBan & ipban = ipban_tab[sort_helper_tab[i]];
|
||||||
|
|
||||||
|
log << log4 << i << ": ip: " << ipban.ip << ", flags: " << ipban.flags << ", last_used: ";
|
||||||
|
|
||||||
|
pt::Date date(ipban.last_used);
|
||||||
|
log << date << ", expires: ";
|
||||||
|
|
||||||
|
date = ipban.expires;
|
||||||
|
log << date << logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IPBanContainer::SortByLastUsedHelper::operator()(size_t index1, size_t index2)
|
||||||
|
{
|
||||||
|
if( index1 < container->ipban_tab.size() &&
|
||||||
|
index2 < container->ipban_tab.size() )
|
||||||
|
{
|
||||||
|
IPBan & ip1 = container->ipban_tab[index1];
|
||||||
|
IPBan & ip2 = container->ipban_tab[index2];
|
||||||
|
|
||||||
|
// prefer to select records which do not have WINIX_IPBAN_FLAG_ACTIVE
|
||||||
|
if( ip1.HasFlag(WINIX_IPBAN_FLAG_ACTIVE) !=
|
||||||
|
ip2.HasFlag(WINIX_IPBAN_FLAG_ACTIVE) )
|
||||||
|
{
|
||||||
|
return ip2.HasFlag(WINIX_IPBAN_FLAG_ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip1.last_used < ip2.last_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
IPBan * IPBanContainer::FindIP(int ip)
|
||||||
|
{
|
||||||
|
// !! IMPROVE ME add binary search if is_ipban_tab_sorted is true
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<ipban_tab.size() ; ++i)
|
||||||
|
{
|
||||||
|
if( ipban_tab[i].ip == ip )
|
||||||
|
{
|
||||||
|
return &ipban_tab[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IPBan & IPBanContainer::GetIPBan(size_t index)
|
||||||
|
{
|
||||||
|
return ipban_tab[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IPBanContainer::Sort()
|
||||||
|
{
|
||||||
|
std::sort(ipban_tab.begin(), ipban_tab.end(), SortIPBansFunction);
|
||||||
|
is_ipban_tab_sorted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
size_t IPBanContainer::Size()
|
||||||
|
{
|
||||||
|
return ipban_tab.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool IPBanContainer::SortIPBansFunction(const IPBan & ip1, const IPBan & ip2)
|
||||||
|
{
|
||||||
|
return ip1.ip < ip2.ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2018, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_ipbancontainer
|
||||||
|
#define headerfile_winix_core_ipbancontainer
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "ipban.h"
|
||||||
|
#include "winixmodeldeprecated.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class IPBanContainer : public WinixModelDeprecated
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
IPBanContainer();
|
||||||
|
|
||||||
|
IPBan & AddIP(int ip);
|
||||||
|
IPBan * FindIP(int ip);
|
||||||
|
void Sort();
|
||||||
|
size_t Size();
|
||||||
|
IPBan & GetIPBan(size_t index);
|
||||||
|
void SetMaxSize(size_t soft_size, size_t size);
|
||||||
|
void RemoveIP(int ip);
|
||||||
|
void Clear();
|
||||||
|
bool IsSorted();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::vector<IPBan> ipban_tab;
|
||||||
|
bool is_ipban_tab_sorted;
|
||||||
|
size_t soft_max_size, max_size;
|
||||||
|
std::vector<size_t> sort_helper_tab;
|
||||||
|
|
||||||
|
static bool SortIPBansFunction(const IPBan & ip1, const IPBan & ip2);
|
||||||
|
void RemoveOldRecords();
|
||||||
|
void PrintTab();
|
||||||
|
void PrintTab2();
|
||||||
|
|
||||||
|
struct SortByLastUsedHelper
|
||||||
|
{
|
||||||
|
IPBanContainer * container;
|
||||||
|
|
||||||
|
SortByLastUsedHelper(IPBanContainer * c) : container(c) {}
|
||||||
|
bool operator()(size_t index1, size_t index2);
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,444 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "job.h"
|
||||||
|
#include "plugin.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "functions/functions.h"
|
||||||
|
#include "lock.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Job::Job()
|
||||||
|
{
|
||||||
|
jobs_queue_tab.resize(PRIORITY_HIGHEST + 1);
|
||||||
|
cur = nullptr;
|
||||||
|
functions = nullptr;
|
||||||
|
mounts = nullptr;
|
||||||
|
load_avg = nullptr;
|
||||||
|
req_tab = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Job::SetCur(Cur * cur)
|
||||||
|
{
|
||||||
|
this->cur = cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Job::SetFunctions(Functions * functions)
|
||||||
|
{
|
||||||
|
this->functions = functions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Job::SetLoadAvg(LoadAvg * load_avg)
|
||||||
|
{
|
||||||
|
this->load_avg = load_avg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Job::SetMounts(Mounts * mounts)
|
||||||
|
{
|
||||||
|
this->mounts = mounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Job::SetReqTab(std::list<Request> * req_tab)
|
||||||
|
{
|
||||||
|
this->req_tab = req_tab;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Job::CheckPriority(size_t & priority) const
|
||||||
|
{
|
||||||
|
if( priority > PRIORITY_HIGHEST )
|
||||||
|
priority = PRIORITY_HIGHEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// first thread (objects locked)
|
||||||
|
void Job::Add(pt::Space & job, size_t priority)
|
||||||
|
{
|
||||||
|
CheckPriority(priority);
|
||||||
|
JobTask task;
|
||||||
|
task.job_type = JobTask::JOB_TYPE_DEFAULT;
|
||||||
|
task.job_id = JobTask::JOB_ID_DEFAULT;
|
||||||
|
task.job = job;
|
||||||
|
jobs_queue_tab[priority].push(task);
|
||||||
|
WakeUpThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// first thread (objects locked)
|
||||||
|
void Job::Add(Request * request, pt::Space & job, size_t priority)
|
||||||
|
{
|
||||||
|
CheckPriority(priority);
|
||||||
|
JobTask task;
|
||||||
|
task.job_type = JobTask::JOB_TYPE_REQUEST_CONTINUATION;
|
||||||
|
task.job_id = JobTask::JOB_ID_DEFAULT;
|
||||||
|
task.request = request;
|
||||||
|
task.job = job;
|
||||||
|
jobs_queue_tab[priority].push(task);
|
||||||
|
WakeUpThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// first thread (objects locked)
|
||||||
|
void Job::Add(long job_id, pt::Space & job, size_t priority)
|
||||||
|
{
|
||||||
|
CheckPriority(priority);
|
||||||
|
JobTask task;
|
||||||
|
task.job_type = JobTask::JOB_TYPE_DEFAULT;
|
||||||
|
task.job_id = job_id;
|
||||||
|
task.job = job;
|
||||||
|
jobs_queue_tab[priority].push(task);
|
||||||
|
WakeUpThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// first thread (objects locked)
|
||||||
|
void Job::Add(long job_id, Request * request, pt::Space & job, size_t priority)
|
||||||
|
{
|
||||||
|
CheckPriority(priority);
|
||||||
|
JobTask task;
|
||||||
|
task.job_type = JobTask::JOB_TYPE_REQUEST_CONTINUATION;
|
||||||
|
task.job_id = job_id;
|
||||||
|
task.request = request;
|
||||||
|
task.job = job;
|
||||||
|
jobs_queue_tab[priority].push(task);
|
||||||
|
WakeUpThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Job::RegisterRequestJob(long job_id, RequestJobBase & request_job)
|
||||||
|
{
|
||||||
|
request_jobs.insert(std::make_pair(job_id, &request_job));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t Job::Size(size_t priority) const
|
||||||
|
{
|
||||||
|
CheckPriority(priority);
|
||||||
|
return jobs_queue_tab[priority].size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
size_t Job::Size() const
|
||||||
|
{
|
||||||
|
size_t sum = 0;
|
||||||
|
|
||||||
|
for(size_t i=0 ; i <= PRIORITY_HIGHEST ; ++i)
|
||||||
|
sum += Size(i);
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Job::Empty(size_t priority) const
|
||||||
|
{
|
||||||
|
CheckPriority(priority);
|
||||||
|
return jobs_queue_tab[priority].empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Job::Empty() const
|
||||||
|
{
|
||||||
|
for(size_t i=0 ; i <= PRIORITY_HIGHEST ; ++i)
|
||||||
|
if( !Empty(i) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
second thread
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects locked)
|
||||||
|
bool Job::SignalReceived()
|
||||||
|
{
|
||||||
|
return !Empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects not locked)
|
||||||
|
void Job::Do()
|
||||||
|
{
|
||||||
|
size_t i = PRIORITY_HIGHEST + 1;
|
||||||
|
bool is_empty;
|
||||||
|
|
||||||
|
while( i-- > 0 && !IsExitSignal() )
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Winix::Lock lock(synchro);
|
||||||
|
is_empty = Empty(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !is_empty )
|
||||||
|
DoQueue(jobs_queue_tab[i], i);
|
||||||
|
}
|
||||||
|
while( !is_empty && !IsExitSignal() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects not locked, jobs_queue is not empty)
|
||||||
|
void Job::DoQueue(JobsQueue & jobs_queue, size_t priority)
|
||||||
|
{
|
||||||
|
bool is_empty;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// references will not be invalidated after insertion to jobs_queue
|
||||||
|
// (jobs_queue is std::queue and it uses std::deque by default)
|
||||||
|
JobTask * job_task = nullptr;
|
||||||
|
|
||||||
|
{
|
||||||
|
Winix::Lock lock(synchro);
|
||||||
|
|
||||||
|
if( !jobs_queue.empty() )
|
||||||
|
{
|
||||||
|
job_task = &jobs_queue.front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( job_task )
|
||||||
|
{
|
||||||
|
DoJob(*job_task, priority);
|
||||||
|
|
||||||
|
{
|
||||||
|
Winix::Lock lock(synchro);
|
||||||
|
|
||||||
|
jobs_queue.pop();
|
||||||
|
is_empty = jobs_queue.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while( !is_empty && !IsExitSignal() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects not locked)
|
||||||
|
void Job::DoJob(JobTask & task, size_t priority)
|
||||||
|
{
|
||||||
|
PluginRes res;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
main_log << logsave;
|
||||||
|
|
||||||
|
if( task.job_type == JobTask::JOB_TYPE_REQUEST_CONTINUATION )
|
||||||
|
{
|
||||||
|
res = DoRequestJobs(task, task.job_id, priority);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res = plugin->Call(model_connector, &log, nullptr, WINIX_JOB, &task.job, nullptr, task.job_type, task.job_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
log << logsave;
|
||||||
|
|
||||||
|
if( res.res_true == 0 )
|
||||||
|
{
|
||||||
|
DoWinixJob(task.job); // probably this will be removed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
log << log2 << "Job: an exception was catched when doing a job" << logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects not locked)
|
||||||
|
PluginRes Job::DoRequestJobs(JobTask & task, long job_id, size_t priority)
|
||||||
|
{
|
||||||
|
PluginRes res;
|
||||||
|
|
||||||
|
if( task.request )
|
||||||
|
{
|
||||||
|
auto jobs_iterator = request_jobs.lower_bound(job_id);
|
||||||
|
bool has_job = false;
|
||||||
|
|
||||||
|
while( jobs_iterator != request_jobs.end() && jobs_iterator->first == job_id )
|
||||||
|
{
|
||||||
|
task.request->run_state = Request::RunState::job_run;
|
||||||
|
jobs_iterator->second->set_dependency(this);
|
||||||
|
jobs_iterator->second->set_request(task.request);
|
||||||
|
jobs_iterator->second->do_job();
|
||||||
|
jobs_iterator++;
|
||||||
|
has_job = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !has_job )
|
||||||
|
{
|
||||||
|
log << log2 << "Job: I could not find a request job with id: " << job_id << logend;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cur local_cur;
|
||||||
|
local_cur.request = task.request;
|
||||||
|
local_cur.request->run_state = Request::RunState::job_run;
|
||||||
|
local_cur.session = task.request->session;
|
||||||
|
local_cur.mount = task.request->mount;
|
||||||
|
|
||||||
|
{
|
||||||
|
Winix::Lock lock(synchro);
|
||||||
|
log << logsave;
|
||||||
|
Cur old_cur = *cur;
|
||||||
|
*cur = local_cur;
|
||||||
|
DoRequestContinuationJob(task, priority);
|
||||||
|
*cur = old_cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log << log2 << "Job: request continuation task doesn't have a request set, skipping the job and request continuation" << logend;
|
||||||
|
log << log2 << "Job: this is an internal error, the request if exists in the queue will never be removed" << logend;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects locked)
|
||||||
|
// use main_log (after locking) for the logs to be in the correct order
|
||||||
|
void Job::DoRequestContinuationJob(JobTask & job_task, size_t priority)
|
||||||
|
{
|
||||||
|
if( cur->request->function )
|
||||||
|
{
|
||||||
|
main_log << config->log_delimiter << logend;
|
||||||
|
main_log << log3 << "Job: making a continuation for request " << cur->request << logend;
|
||||||
|
main_log << log4 << "Job: doing directory analysis again" << logend;
|
||||||
|
|
||||||
|
if( functions->ParseOnlyDirs() )
|
||||||
|
{
|
||||||
|
cur->mount = mounts->CalcCurMount(cur->request);
|
||||||
|
cur->request->mount = cur->mount;
|
||||||
|
cur->request->run_state = Request::RunState::job_continuation_run;
|
||||||
|
functions->ContinueMakeFunction();
|
||||||
|
|
||||||
|
if( cur->request->run_state == Request::RunState::assigned_to_job )
|
||||||
|
{
|
||||||
|
log << log3 << "Job: this request (" << cur->request << ") has been moved to the job queue again" << logend;
|
||||||
|
Add(cur->request->job_id, cur->request, cur->request->job, priority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
main_log << log4 << "Job: directories have not been correctly prepared, finishing the request" << logend;
|
||||||
|
cur->request->http_status = Header::status_500_internal_server_error;
|
||||||
|
cur->request->run_state = Request::RunState::prepare_to_finish;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
main_log << log2 << "Job: request continuation task doesn't have a funtion set, return 500 internal error" << logend;
|
||||||
|
cur->request->http_status = Header::status_500_internal_server_error;
|
||||||
|
cur->request->run_state = Request::RunState::prepare_to_finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cur->request->run_state != Request::RunState::assigned_to_job )
|
||||||
|
{
|
||||||
|
cur->request->FinishRequest(); // if cur->request->function were null then templates functions would not work
|
||||||
|
load_avg->StopRequest(cur->request);
|
||||||
|
|
||||||
|
if( cur->request->function )
|
||||||
|
cur->request->function->clear();
|
||||||
|
|
||||||
|
cur->request->Clear();
|
||||||
|
cur->request->run_state = Request::RunState::finished;
|
||||||
|
RemoveOldRequest(cur->request);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( cur->request->function )
|
||||||
|
cur->request->function->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
main_log << logendrequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects not locked)
|
||||||
|
void Job::DoWinixJob(pt::Space & job)
|
||||||
|
{
|
||||||
|
//log << log1 << "standard winix job: " << job.Text(L"type") << logend;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// second thread (objects locked)
|
||||||
|
// use main_log for the logs to be in the correct order
|
||||||
|
void Job::RemoveOldRequest(Request * request)
|
||||||
|
{
|
||||||
|
std::list<Request>::iterator i = req_tab->begin();
|
||||||
|
|
||||||
|
while( i != req_tab->end() )
|
||||||
|
{
|
||||||
|
if( &(*i) == request )
|
||||||
|
{
|
||||||
|
main_log << log3 << "Job: removing request " << request << logend;
|
||||||
|
req_tab->erase(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2023, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_job
|
||||||
|
#define headerfile_winix_core_job
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <queue>
|
||||||
|
#include "basethread.h"
|
||||||
|
#include "space/space.h"
|
||||||
|
#include "jobtask.h"
|
||||||
|
#include "cur.h"
|
||||||
|
#include "loadavg.h"
|
||||||
|
#include "mounts.h"
|
||||||
|
#include "requestjobs/requestjobbase.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
class Functions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Job : public BaseThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static const size_t PRIORITY_LOWEST = 0;
|
||||||
|
static const size_t PRIORITY_HIGHEST = 31;
|
||||||
|
|
||||||
|
static const size_t PRIORITY_DEFAULT = 16;
|
||||||
|
static const size_t PRIORITY_REQUEST_CONTINUATION = 17;
|
||||||
|
|
||||||
|
|
||||||
|
Job();
|
||||||
|
|
||||||
|
void SetCur(Cur * cur);
|
||||||
|
void SetFunctions(Functions * functions);
|
||||||
|
void SetLoadAvg(LoadAvg * load_avg);
|
||||||
|
void SetMounts(Mounts * mounts);
|
||||||
|
void SetReqTab(std::list<Request> * req_tab);
|
||||||
|
|
||||||
|
/*
|
||||||
|
add a new job to the queue
|
||||||
|
priority: 0-31 (0 - the lowest priority, 31 - the highest priority)
|
||||||
|
*/
|
||||||
|
void Add(pt::Space & job, size_t priority = PRIORITY_DEFAULT);
|
||||||
|
void Add(Request * request, pt::Space & job, size_t priority = PRIORITY_DEFAULT);
|
||||||
|
|
||||||
|
void Add(long job_id, pt::Space & job, size_t priority = PRIORITY_DEFAULT);
|
||||||
|
void Add(long job_id, Request * request, pt::Space & job, size_t priority = PRIORITY_DEFAULT);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* register a new request job worker
|
||||||
|
*/
|
||||||
|
void RegisterRequestJob(long job_id, RequestJobBase & request_job);
|
||||||
|
|
||||||
|
/*
|
||||||
|
queue size, and size of all jobs in any priority
|
||||||
|
*/
|
||||||
|
size_t Size(size_t priority) const;
|
||||||
|
size_t Size() const;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
true if specified queue is empty
|
||||||
|
or if all queues are empty
|
||||||
|
*/
|
||||||
|
bool Empty(size_t priority) const;
|
||||||
|
bool Empty() const;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Cur * cur;
|
||||||
|
Functions * functions;
|
||||||
|
LoadAvg * load_avg;
|
||||||
|
Mounts * mounts;
|
||||||
|
std::list<Request> * req_tab;
|
||||||
|
|
||||||
|
typedef std::queue<JobTask> JobsQueue;
|
||||||
|
typedef std::vector<JobsQueue> JobsQueueTab;
|
||||||
|
JobsQueueTab jobs_queue_tab;
|
||||||
|
std::multimap<long, RequestJobBase*> request_jobs;
|
||||||
|
|
||||||
|
void CheckPriority(size_t & priority) const;
|
||||||
|
void SaveToFile();
|
||||||
|
void ReadFromFile();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
second thread
|
||||||
|
*/
|
||||||
|
|
||||||
|
// standard winix jobs
|
||||||
|
// Image image;
|
||||||
|
// sending emails
|
||||||
|
// etc.
|
||||||
|
|
||||||
|
bool SignalReceived();
|
||||||
|
void Do();
|
||||||
|
void DoQueue(JobsQueue & jobs_queue, size_t priority);
|
||||||
|
void DoJob(JobTask & task, size_t priority);
|
||||||
|
void DoRequestContinuationJob(JobTask & job_task, size_t priority);
|
||||||
|
void DoWinixJob(pt::Space & job);
|
||||||
|
void RemoveOldRequest(Request * request);
|
||||||
|
void RemoveAllJobsRequests();
|
||||||
|
PluginRes DoRequestJobs(JobTask & task, long job_id, size_t priority);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_jobtask
|
||||||
|
#define headerfile_winix_core_jobtask
|
||||||
|
|
||||||
|
#include "space/space.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
class Request;
|
||||||
|
|
||||||
|
|
||||||
|
class JobTask
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static const long JOB_TYPE_DEFAULT = 1;
|
||||||
|
static const long JOB_TYPE_REQUEST_CONTINUATION = 2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the value of job_id will be defined by each controller
|
||||||
|
* so the default value is better to have -1 instead of for example 1
|
||||||
|
*/
|
||||||
|
static const long JOB_ID_DEFAULT = -1;
|
||||||
|
|
||||||
|
long job_type;
|
||||||
|
long job_id;
|
||||||
|
Request * request;
|
||||||
|
pt::Space job;
|
||||||
|
|
||||||
|
|
||||||
|
JobTask()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
job_type = JOB_TYPE_DEFAULT;
|
||||||
|
job_id = JOB_ID_DEFAULT;
|
||||||
|
request = nullptr;
|
||||||
|
job.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2014, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "lastcontainer.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LastItem::LastItem()
|
||||||
|
{
|
||||||
|
user_id = 0;
|
||||||
|
ip = 0;
|
||||||
|
session_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LastItem::IsLoggedOut()
|
||||||
|
{
|
||||||
|
return end.year > 1970;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LastContainer::Iterator LastContainer::Begin()
|
||||||
|
{
|
||||||
|
return last_tab.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LastContainer::Iterator LastContainer::End()
|
||||||
|
{
|
||||||
|
return last_tab.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LastContainer::Iterator LastContainer::FindNotLoggedOut(long user_id, long session_id)
|
||||||
|
{
|
||||||
|
LastTab::iterator i;
|
||||||
|
|
||||||
|
for(i=last_tab.begin() ; i!=last_tab.end() ; ++i)
|
||||||
|
{
|
||||||
|
if( i->user_id == user_id && i->session_id == session_id && !i->IsLoggedOut() )
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return last_tab.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void LastContainer::UserLogin(long user_id, const std::wstring & name, unsigned int ip, long session_id)
|
||||||
|
{
|
||||||
|
LastTab::iterator i = FindNotLoggedOut(user_id, session_id);
|
||||||
|
|
||||||
|
if( i != last_tab.end() )
|
||||||
|
{
|
||||||
|
log << log1 << "LC: such a user and session_id exist, not added as a new one" << logend;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( last_tab.size() >= WINIX_LASTCONTAINER_TABLE_SIZE ) // last_tab has O(n) complexity
|
||||||
|
last_tab.erase(last_tab.begin());
|
||||||
|
|
||||||
|
LastItem li;
|
||||||
|
|
||||||
|
li.user_id = user_id;
|
||||||
|
li.name = name;
|
||||||
|
li.ip = ip;
|
||||||
|
li.session_id = session_id;
|
||||||
|
li.start = std::time(0);
|
||||||
|
|
||||||
|
last_tab.insert(last_tab.end(), li);
|
||||||
|
|
||||||
|
log << log2 << "LC: added user: " << name << " into the last table" << logend;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void LastContainer::UserLogout(long user_id, long session_id)
|
||||||
|
{
|
||||||
|
LastTab::iterator i = FindNotLoggedOut(user_id, session_id);
|
||||||
|
|
||||||
|
if( i != last_tab.end() )
|
||||||
|
{
|
||||||
|
i->end = std::time(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
!! IMPROVE ME
|
||||||
|
users read from the session file (at boot time)
|
||||||
|
are not added to LastContainer
|
||||||
|
*/
|
||||||
|
|
||||||
|
log << log4 << "LC: there is no such a user to log out: user_id: "
|
||||||
|
<< user_id << " ses_id: " << session_id << logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2014, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_lastcontainer
|
||||||
|
#define headerfile_winix_core_lastcontainer
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
#include <cstring>
|
||||||
|
#include <ctime>
|
||||||
|
#include "date/date.h"
|
||||||
|
#include "winixbase.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// how many items we store in the 'last' function
|
||||||
|
#define WINIX_LASTCONTAINER_TABLE_SIZE 100
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct LastItem
|
||||||
|
{
|
||||||
|
long user_id;
|
||||||
|
|
||||||
|
// additional we store the whole string-name
|
||||||
|
// (you can delete a user from the database but we can still print the name)
|
||||||
|
std::wstring name;
|
||||||
|
|
||||||
|
// ip address
|
||||||
|
unsigned int ip;
|
||||||
|
|
||||||
|
// session id (used when logging out)
|
||||||
|
long session_id;
|
||||||
|
|
||||||
|
// start logging and end logging
|
||||||
|
pt::Date start;
|
||||||
|
pt::Date end;
|
||||||
|
|
||||||
|
|
||||||
|
LastItem();
|
||||||
|
bool IsLoggedOut();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class LastContainer : public WinixBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef std::list<LastItem> LastTab;
|
||||||
|
typedef LastTab::iterator Iterator;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Iterator Begin();
|
||||||
|
Iterator End();
|
||||||
|
void UserLogin(long user_id, const std::wstring & name, unsigned int ip, long session_id);
|
||||||
|
void UserLogout(long user_id, long session_id);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
LastTab last_tab;
|
||||||
|
Iterator FindNotLoggedOut(long user_id, long session_id);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,406 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2018, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "loadavg.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LoadAvg::LoadAvg()
|
||||||
|
{
|
||||||
|
current1.Clear();
|
||||||
|
current5.Clear();
|
||||||
|
current15.Clear();
|
||||||
|
|
||||||
|
cache_load1 = 0.0;
|
||||||
|
cache_load5 = 0.0;
|
||||||
|
cache_load15 = 0.0;
|
||||||
|
|
||||||
|
cache_req_per_sec1 = 0.0;
|
||||||
|
cache_req_per_sec5 = 0.0;
|
||||||
|
cache_req_per_sec15 = 0.0;
|
||||||
|
|
||||||
|
timespec_old_req_stop.tv_sec = 0;
|
||||||
|
timespec_old_req_stop.tv_nsec = 0;
|
||||||
|
|
||||||
|
CreateTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LoadAvg & LoadAvg::operator=(const LoadAvg & l)
|
||||||
|
{
|
||||||
|
current1 = l.current1;
|
||||||
|
current5 = l.current5;
|
||||||
|
current15 = l.current15;
|
||||||
|
|
||||||
|
cache_load1 = l.cache_load1;
|
||||||
|
cache_load5 = l.cache_load5;
|
||||||
|
cache_load15 = l.cache_load15;
|
||||||
|
|
||||||
|
cache_req_per_sec1 = l.cache_req_per_sec1;
|
||||||
|
cache_req_per_sec5 = l.cache_req_per_sec5;
|
||||||
|
cache_req_per_sec15 = l.cache_req_per_sec15;
|
||||||
|
|
||||||
|
timespec_old_req_stop.tv_sec = l.timespec_old_req_stop.tv_sec;
|
||||||
|
timespec_old_req_stop.tv_nsec = l.timespec_old_req_stop.tv_nsec;
|
||||||
|
|
||||||
|
CreateTable();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LoadAvg::LoadAvg(const LoadAvg & l)
|
||||||
|
{
|
||||||
|
operator=(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LoadAvg::~LoadAvg()
|
||||||
|
{
|
||||||
|
delete [] tab1;
|
||||||
|
delete [] tab5;
|
||||||
|
delete [] tab15;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void LoadAvg::CreateTable(size_t seconds, size_t granularity, Times* & tab, size_t & len)
|
||||||
|
{
|
||||||
|
len = (seconds / granularity) + 1; // rounding up (len mininum is 1)
|
||||||
|
tab = new Times[len];
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<len ; ++i)
|
||||||
|
{
|
||||||
|
tab[i].Clear();
|
||||||
|
tab[i].dp = granularity; // at the beginning we assume the pause for all items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LoadAvg::CreateTable()
|
||||||
|
{
|
||||||
|
CreateTable(60, WINIX_LOADAVG_GRANULARITY1, tab1, len1);
|
||||||
|
CreateTable(60 * 5, WINIX_LOADAVG_GRANULARITY5, tab5, len5);
|
||||||
|
CreateTable(60 * 15, WINIX_LOADAVG_GRANULARITY15, tab15, len15);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void LoadAvg::MoveTab(Times * tab, size_t len)
|
||||||
|
{
|
||||||
|
if( len > 1 )
|
||||||
|
{
|
||||||
|
for(size_t i=0 ; i<len-1 ; ++i)
|
||||||
|
tab[i] = tab[i+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
tab[len-1].Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LoadAvg::UpdateTimer1()
|
||||||
|
{
|
||||||
|
MoveTab(tab1, len1);
|
||||||
|
|
||||||
|
tab1[len1-1] = current1;
|
||||||
|
current1.Clear();
|
||||||
|
cache_load1 = 0.0;
|
||||||
|
cache_req_per_sec1 = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LoadAvg::UpdateTimer5()
|
||||||
|
{
|
||||||
|
MoveTab(tab5, len5);
|
||||||
|
|
||||||
|
tab5[len5-1] = current5;
|
||||||
|
current5.Clear();
|
||||||
|
cache_load5 = 0.0;
|
||||||
|
cache_req_per_sec5 = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void LoadAvg::UpdateTimer15()
|
||||||
|
{
|
||||||
|
MoveTab(tab15, len15);
|
||||||
|
|
||||||
|
tab15[len15-1] = current15;
|
||||||
|
current15.Clear();
|
||||||
|
cache_load15 = 0.0;
|
||||||
|
cache_req_per_sec15 = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LoadAvg::CheckTimers()
|
||||||
|
{
|
||||||
|
if( current1.dr + current1.dp > (double)WINIX_LOADAVG_GRANULARITY1 )
|
||||||
|
UpdateTimer1();
|
||||||
|
|
||||||
|
if( current5.dr + current5.dp > (double)WINIX_LOADAVG_GRANULARITY5 )
|
||||||
|
UpdateTimer5();
|
||||||
|
|
||||||
|
if( current15.dr + current15.dp > (double)WINIX_LOADAVG_GRANULARITY15 )
|
||||||
|
UpdateTimer15();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void LoadAvg::StartRequest(Request * req)
|
||||||
|
{
|
||||||
|
if( timespec_old_req_stop.tv_sec != 0 )
|
||||||
|
{
|
||||||
|
// we got at least one request in the past
|
||||||
|
timespec diff;
|
||||||
|
calculate_timespec_diff(timespec_old_req_stop, req->timespec_req_start, diff);
|
||||||
|
double dp = timespec_to_double(diff);
|
||||||
|
|
||||||
|
current1.dp += dp;
|
||||||
|
current5.dp += dp;
|
||||||
|
current15.dp += dp;
|
||||||
|
|
||||||
|
CheckTimers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void LoadAvg::StopRequest(Request * req)
|
||||||
|
{
|
||||||
|
double dr = timespec_to_double(req->timespec_req_diff);
|
||||||
|
|
||||||
|
current1.dr += dr;
|
||||||
|
current5.dr += dr;
|
||||||
|
current15.dr += dr;
|
||||||
|
|
||||||
|
current1.req += 1;
|
||||||
|
current5.req += 1;
|
||||||
|
current15.req += 1;
|
||||||
|
|
||||||
|
timespec_old_req_stop = req->timespec_req_stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LoadAvg::SumTab(Times * tab, size_t len, double expected, Times & t)
|
||||||
|
{
|
||||||
|
size_t i = len;
|
||||||
|
|
||||||
|
while( i-- > 0 && t.dr+t.dp < expected )
|
||||||
|
{
|
||||||
|
t.dr += tab[i].dr;
|
||||||
|
t.dp += tab[i].dp;
|
||||||
|
t.req += tab[i].req;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LoadAvg::Calculate1()
|
||||||
|
{
|
||||||
|
Times t = current1;
|
||||||
|
|
||||||
|
SumTab(tab1, len1, 60.0, t);
|
||||||
|
|
||||||
|
if( t.dr+t.dp == 0.0 )
|
||||||
|
{
|
||||||
|
cache_load1 = 0.0;
|
||||||
|
cache_req_per_sec1 = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cache_load1 = t.dr / (t.dr+t.dp);
|
||||||
|
cache_req_per_sec1 = t.req / (t.dr+t.dp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LoadAvg::Calculate5()
|
||||||
|
{
|
||||||
|
Times t = current5;
|
||||||
|
|
||||||
|
SumTab(tab5, len5, 60.0 * 5, t);
|
||||||
|
|
||||||
|
if( t.dr+t.dp == 0.0 )
|
||||||
|
{
|
||||||
|
cache_load5 = 0.0;
|
||||||
|
cache_req_per_sec5 = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cache_load5 = t.dr / (t.dr+t.dp);
|
||||||
|
cache_req_per_sec5 = t.req / (t.dr+t.dp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LoadAvg::Calculate15()
|
||||||
|
{
|
||||||
|
Times t = current15;
|
||||||
|
|
||||||
|
SumTab(tab15, len15, 60.0 * 15, t);
|
||||||
|
|
||||||
|
if( t.dr+t.dp == 0.0 )
|
||||||
|
{
|
||||||
|
cache_load15 = 0.0;
|
||||||
|
cache_req_per_sec15 = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cache_load15 = t.dr / (t.dr+t.dp);
|
||||||
|
cache_req_per_sec15 = t.req / (t.dr+t.dp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double LoadAvg::LoadAvgNow()
|
||||||
|
{
|
||||||
|
double load = 0.0;
|
||||||
|
|
||||||
|
double dr = current1.dr;
|
||||||
|
double dp = current1.dp;
|
||||||
|
|
||||||
|
if( tab1[len1-1].dr + tab1[len1-1].dp < WINIX_LOADAVG_GRANULARITY1 * 2 )
|
||||||
|
{
|
||||||
|
dr += tab1[len1-1].dr;
|
||||||
|
dp += tab1[len1-1].dp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( dr + dp != 0.0 )
|
||||||
|
load = dr / (dr + dp);
|
||||||
|
|
||||||
|
return load;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
double LoadAvg::LoadAvg1()
|
||||||
|
{
|
||||||
|
if( cache_load1 != 0.0 )
|
||||||
|
return cache_load1;
|
||||||
|
|
||||||
|
Calculate1();
|
||||||
|
|
||||||
|
return cache_load1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double LoadAvg::LoadAvg5()
|
||||||
|
{
|
||||||
|
if( cache_load5 != 0.0 )
|
||||||
|
return cache_load5;
|
||||||
|
|
||||||
|
Calculate5();
|
||||||
|
|
||||||
|
return cache_load5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double LoadAvg::LoadAvg15()
|
||||||
|
{
|
||||||
|
if( cache_load15 != 0.0 )
|
||||||
|
return cache_load15;
|
||||||
|
|
||||||
|
Calculate15();
|
||||||
|
|
||||||
|
return cache_load15;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
double LoadAvg::ReqPerSecNow()
|
||||||
|
{
|
||||||
|
double req_per_sec = 0.0;
|
||||||
|
|
||||||
|
double dr = current1.dr;
|
||||||
|
double dp = current1.dp;
|
||||||
|
double req = current1.req;
|
||||||
|
|
||||||
|
if( tab1[len1-1].dr + tab1[len1-1].dp < WINIX_LOADAVG_GRANULARITY1 * 2 )
|
||||||
|
{
|
||||||
|
dr += tab1[len1-1].dr;
|
||||||
|
dp += tab1[len1-1].dp;
|
||||||
|
req += tab1[len1-1].req;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( dr + dp != 0.0 )
|
||||||
|
req_per_sec = req / (dr + dp);
|
||||||
|
|
||||||
|
return req_per_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double LoadAvg::ReqPerSec1()
|
||||||
|
{
|
||||||
|
if( cache_req_per_sec1 != 0.0 )
|
||||||
|
return cache_req_per_sec1;
|
||||||
|
|
||||||
|
Calculate1();
|
||||||
|
|
||||||
|
return cache_req_per_sec1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double LoadAvg::ReqPerSec5()
|
||||||
|
{
|
||||||
|
if( cache_req_per_sec5 != 0.0 )
|
||||||
|
return cache_req_per_sec5;
|
||||||
|
|
||||||
|
Calculate5();
|
||||||
|
|
||||||
|
return cache_req_per_sec5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double LoadAvg::ReqPerSec15()
|
||||||
|
{
|
||||||
|
if( cache_req_per_sec15 != 0.0 )
|
||||||
|
return cache_req_per_sec15;
|
||||||
|
|
||||||
|
Calculate15();
|
||||||
|
|
||||||
|
return cache_req_per_sec15;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2018, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_loadavg
|
||||||
|
#define headerfile_winix_core_loadavg
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
#include "winixbase.h"
|
||||||
|
#include "request.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// in seconds
|
||||||
|
#define WINIX_LOADAVG_GRANULARITY1 2
|
||||||
|
#define WINIX_LOADAVG_GRANULARITY5 15
|
||||||
|
#define WINIX_LOADAVG_GRANULARITY15 45
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class LoadAvg : public WinixBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LoadAvg();
|
||||||
|
~LoadAvg();
|
||||||
|
LoadAvg & operator=(const LoadAvg & l);
|
||||||
|
LoadAvg(const LoadAvg & l);
|
||||||
|
|
||||||
|
void StartRequest(Request * req);
|
||||||
|
void StopRequest(Request * req);
|
||||||
|
|
||||||
|
double LoadAvgNow(); // load average withing last WINIX_LOADAVG_GRANULARITY1 seconds
|
||||||
|
double LoadAvg1();
|
||||||
|
double LoadAvg5();
|
||||||
|
double LoadAvg15();
|
||||||
|
|
||||||
|
double ReqPerSecNow();
|
||||||
|
double ReqPerSec1();
|
||||||
|
double ReqPerSec5();
|
||||||
|
double ReqPerSec15();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
struct Times
|
||||||
|
{
|
||||||
|
double dr; // time for the request (in seconds)
|
||||||
|
double dp; // time for the pause between requestes(in seconds)
|
||||||
|
long req; // how many requests
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
dr = 0.0;
|
||||||
|
dp = 0.0;
|
||||||
|
req = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Times & operator=(const Times & t)
|
||||||
|
{
|
||||||
|
dr = t.dr;
|
||||||
|
dp = t.dp;
|
||||||
|
req = t.req;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
timespec timespec_old_req_stop;
|
||||||
|
|
||||||
|
void CheckTimers();
|
||||||
|
void UpdateTimer1();
|
||||||
|
void UpdateTimer5();
|
||||||
|
void UpdateTimer15();
|
||||||
|
|
||||||
|
Times current1;
|
||||||
|
Times current5;
|
||||||
|
Times current15;
|
||||||
|
|
||||||
|
void CreateTable(size_t seconds, size_t granulatiry, Times* & tab, size_t & len);
|
||||||
|
void CreateTable();
|
||||||
|
|
||||||
|
void MoveTab(Times * tab, size_t len);
|
||||||
|
void SumTab(Times * tab, size_t len, double expected, Times & t);
|
||||||
|
|
||||||
|
void Calculate1();
|
||||||
|
void Calculate5();
|
||||||
|
void Calculate15();
|
||||||
|
|
||||||
|
|
||||||
|
Times * tab1;
|
||||||
|
size_t len1;
|
||||||
|
|
||||||
|
Times * tab5;
|
||||||
|
size_t len5;
|
||||||
|
|
||||||
|
Times * tab15;
|
||||||
|
size_t len15;
|
||||||
|
|
||||||
|
double cache_load1;
|
||||||
|
double cache_load5;
|
||||||
|
double cache_load15;
|
||||||
|
|
||||||
|
double cache_req_per_sec1;
|
||||||
|
double cache_req_per_sec5;
|
||||||
|
double cache_req_per_sec15;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2014, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lock.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Lock::Lock()
|
||||||
|
{
|
||||||
|
synchro = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Lock::Lock(Synchro * synchro_)
|
||||||
|
{
|
||||||
|
synchro = synchro_;
|
||||||
|
synchro->Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Lock::Lock(Synchro & synchro_)
|
||||||
|
{
|
||||||
|
synchro = &synchro_;
|
||||||
|
synchro->Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Lock::~Lock()
|
||||||
|
{
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Lock::Unlock()
|
||||||
|
{
|
||||||
|
if( synchro )
|
||||||
|
{
|
||||||
|
synchro->Unlock();
|
||||||
|
synchro = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2014, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_winix_core_lock
|
||||||
|
#define headerfile_winix_core_lock
|
||||||
|
|
||||||
|
#include "synchro.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Lock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Lock(Synchro * synchro_);
|
||||||
|
Lock(Synchro & synchro_);
|
||||||
|
|
||||||
|
~Lock();
|
||||||
|
|
||||||
|
void Unlock();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Synchro * synchro;
|
||||||
|
|
||||||
|
Lock();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,384 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of Winix
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
#include <ctime>
|
||||||
|
#include <string.h>
|
||||||
|
#include "utf8/utf8.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Winix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Log::Log()
|
||||||
|
{
|
||||||
|
request = 0;
|
||||||
|
max_requests = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log::~Log()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Log::SetDependency(Log * log)
|
||||||
|
{
|
||||||
|
buffer = log->buffer;
|
||||||
|
file_log = log->file_log;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Log::SetMaxRequests(int max_requests)
|
||||||
|
{
|
||||||
|
this->max_requests = max_requests;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Log::PrintDate(const pt::Date & date)
|
||||||
|
{
|
||||||
|
FileLog * winix_file_log = dynamic_cast<FileLog*>(file_log);
|
||||||
|
|
||||||
|
if( winix_file_log )
|
||||||
|
(*this) << winix_file_log->get_local_date(date); // synchronization is made in get_local_date
|
||||||
|
else
|
||||||
|
(*this) << date;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(const void * s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(const char * s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(const std::string & s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(const std::string * s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(const wchar_t * s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(const std::wstring & s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(const std::wstring * s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(bool s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(short s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(int s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(long s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(long long s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(char s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(unsigned char s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(wchar_t s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(char32_t s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(unsigned short s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(unsigned int s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(unsigned long s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(unsigned long long s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(float s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(double s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(long double s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(const pt::Stream & s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(const pt::Space & s)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(const pt::Date & date)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(date);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(morm::Model & model)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(model);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(LogManipulators m)
|
||||||
|
{
|
||||||
|
switch(m)
|
||||||
|
{
|
||||||
|
case LogManipulators::log1:
|
||||||
|
pt::Log::operator<<(pt::Log::log1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LogManipulators::log2:
|
||||||
|
pt::Log::operator<<(pt::Log::log2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LogManipulators::log3:
|
||||||
|
pt::Log::operator<<(pt::Log::log3);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LogManipulators::log4:
|
||||||
|
pt::Log::operator<<(pt::Log::log4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LogManipulators::logend:
|
||||||
|
pt::Log::operator<<(pt::Log::logend);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LogManipulators::logsave:
|
||||||
|
pt::Log::operator<<(pt::Log::logsave);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LogManipulators::logendrequest:
|
||||||
|
if( ++request >= max_requests )
|
||||||
|
{
|
||||||
|
save_log_and_clear();
|
||||||
|
request = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::operator<<(pt::Log::Manipulators m)
|
||||||
|
{
|
||||||
|
pt::Log::operator<<(m);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Log & Log::SystemErr(int err)
|
||||||
|
//{
|
||||||
|
// (*this) << "errno: " << err;
|
||||||
|
//
|
||||||
|
// // strerror is not thread safe and we now use Log in each thread
|
||||||
|
// const char * err_msg = strerror(err);
|
||||||
|
//
|
||||||
|
// if( err_msg )
|
||||||
|
// (*this) << " (" << err_msg << ")";
|
||||||
|
//
|
||||||
|
// return *this;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Log & Log::put_string(const std::string & value, size_t max_size)
|
||||||
|
{
|
||||||
|
pt::Log::put_string(value, max_size);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::put_string(const std::wstring & value, size_t max_size)
|
||||||
|
{
|
||||||
|
pt::Log::put_string(value, max_size);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log & Log::put_binary_blob(const char * blob, size_t blob_len)
|
||||||
|
{
|
||||||
|
pt::Log::put_binary_blob(blob, blob_len);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log & Log::put_binary_blob(const std::string & blob)
|
||||||
|
{
|
||||||
|
pt::Log::put_binary_blob(blob);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Winix
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user