<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright (C) 2011 - 2015                                                  *
 * Dominik Charousset <dominik.charousset (at) haw-hamburg.de>                *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#ifndef CAF_IO_PUBLISH_HPP
#define CAF_IO_PUBLISH_HPP

#include <set>
#include <string>
#include <cstdint>

#include "caf/actor.hpp"
#include "caf/actor_cast.hpp"
#include "caf/typed_actor.hpp"

namespace caf {
namespace io {

uint16_t publish_impl(uint16_t port, actor_addr whom,
                      std::set<std::string> sigs, const char* in,
                      bool reuse_addr);

/// Publishes `whom` at `port`. The connection is managed by the middleman.
/// @param whom Actor that should be published at `port`.
/// @param port Unused TCP port.
/// @param in The IP address to listen to or `INADDR_ANY` if `in == nullptr`.
/// @returns The actual port the OS uses after `bind()`. If `port == 0` the OS
///          chooses a random high-level port.
/// @throws bind_failure
inline uint16_t publish(caf::actor whom, uint16_t port,
                        const char* in = nullptr, bool reuse_addr = false) {
  if (! whom) {
    return 0;
  }
  return publish_impl(port, whom->address(), {}, in, reuse_addr);
}

/// @copydoc publish(actor,uint16_t,const char*)
template <class... Sigs>
uint16_t typed_publish(typed_actor<Sigs...> whom, uint16_t port,
                       const char* in = nullptr, bool reuse_addr = false) {
  if (! whom) {
    return 0;
  }
  return publish_impl(port, whom->address(), whom.message_types(),
                      in, reuse_addr);
}

} // namespace io
} // namespace caf

#endif // CAF_IO_PUBLISH_HPP
<commit_msg>Fix compiler error on older Clang releases<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright (C) 2011 - 2015                                                  *
 * Dominik Charousset <dominik.charousset (at) haw-hamburg.de>                *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#ifndef CAF_IO_PUBLISH_HPP
#define CAF_IO_PUBLISH_HPP

#include <set>
#include <string>
#include <cstdint>

#include "caf/actor.hpp"
#include "caf/actor_cast.hpp"
#include "caf/typed_actor.hpp"

namespace caf {
namespace io {

uint16_t publish_impl(uint16_t port, actor_addr whom,
                      std::set<std::string> sigs, const char* in,
                      bool reuse_addr);

/// Publishes `whom` at `port`. The connection is managed by the middleman.
/// @param whom Actor that should be published at `port`.
/// @param port Unused TCP port.
/// @param in The IP address to listen to or `INADDR_ANY` if `in == nullptr`.
/// @returns The actual port the OS uses after `bind()`. If `port == 0` the OS
///          chooses a random high-level port.
/// @throws bind_failure
inline uint16_t publish(caf::actor whom, uint16_t port,
                        const char* in = nullptr, bool reuse_addr = false) {
  return ! whom ? 0 : publish_impl(port, whom->address(),
                                   std::set<std::string>{}, in, reuse_addr);
}

/// @copydoc publish(actor,uint16_t,const char*)
template <class... Sigs>
uint16_t typed_publish(typed_actor<Sigs...> whom, uint16_t port,
                       const char* in = nullptr, bool reuse_addr = false) {
  return ! whom ? 0 : publish_impl(port, whom->address(), whom.message_types(),
                                   in, reuse_addr);
}

} // namespace io
} // namespace caf

#endif // CAF_IO_PUBLISH_HPP
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 Nathan Lowe
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * SHA512.cpp - Implementation of SHA2 for 512-bit digests
 */

#include <stdexcept>
#include "SHA512.h"
#include "constants.h"
#include "../libcrypto.h"

/** The number of internal rounds performed on each block of data */
#define SHA512_ROUNDS_PER_BLOCK 80

namespace libcrypto
{
	namespace hashing
	{
		namespace SHA512
		{
			/** The state used across rounds of the hash */
			typedef struct
			{
				uint64_t a = 0x6a09e667f3bcc908;
				uint64_t b = 0xbb67ae8584caa73b;
				uint64_t c = 0x3c6ef372fe94f82b;
				uint64_t d = 0xa54ff53a5f1d36f1;
				uint64_t e = 0x510e527fade682d1;
				uint64_t f = 0x9b05688c2b3e6c1f;
				uint64_t g = 0x1f83d9abfb41bd6b;
				uint64_t h = 0x5be0cd19137e2179;

				uint64_t W[SHA512_ROUNDS_PER_BLOCK] = { 0 };
			}State;

			/** A 1024-bit block that SHA512 Operates on */
			typedef struct
			{
				uint64_t& operator[](size_t idx) { return M[idx]; }
				uint64_t M[16] = { 0 };
			}MessageBlock;

			/** Choose Functipn: Bit i is selected from y if it is set in x, otherwise it is selected from z */
			inline uint64_t ch(uint64_t x, uint64_t y, uint64_t z)
			{
				return (x & y) ^ (~x & z);
			}

			/** Majority Function: Bit i is set if it is set in at least two of three inputs */
			inline uint64_t maj(uint64_t x, uint64_t y, uint64_t z)
			{
				return (x & y) ^ (x & z) ^ (y & z);
			}

			/** Right-rotate x by the specified amount */
			inline uint64_t rotr(uint64_t x, uint8_t n)
			{
				return x >> n | x << (64 - n);
			}

			/** Big-Sigma 0 from FIPS 1SHA512_ROUNDS_PER_BLOCK-4 */
			inline uint64_t SIGMA0(uint64_t x)
			{
				return rotr(x, 28) ^ rotr(x, 34) ^ rotr(x, 39);
			}

			/** Big-Sigma 0 from FIPS 1SHA512_ROUNDS_PER_BLOCK-4 */
			inline uint64_t SIGMA1(uint64_t x)
			{
				return rotr(x, 14) ^ rotr(x, 18) ^ rotr(x, 41);
			}

			/** Little-Sigma 0 from FIPS 1SHA512_ROUNDS_PER_BLOCK-4 */
			inline uint64_t sigma0(uint64_t x)
			{
				return rotr(x, 1) ^ rotr(x, 8) ^ (x >> 7);
			}

			/** Little-Sigma 1 from FIPS 1SHA512_ROUNDS_PER_BLOCK-4 */
			inline uint64_t sigma1(uint64_t x)
			{
				return rotr(x, 19) ^ rotr(x, 61) ^ (x >> 6);
			}

			/** Generate the word schedule for the round from the specified message block */
			inline void GenSchedule(State* state, MessageBlock M)
			{
				for(auto t = 0; t < 16; t++)
				{
					state->W[t] = M[t];
				}
				for(auto t = 16; t < SHA512_ROUNDS_PER_BLOCK; t++)
				{
					state->W[t] = sigma1(state->W[t - 2]) + state->W[t - 7] + sigma0(state->W[t - 15]) + state->W[t - 16];
				}
			}

			/** Perform an iteration of SHA512 on the specified message block */
			inline void round(State* state, MessageBlock M)
			{
				auto a = state->a;
				auto b = state->b;
				auto c = state->c;
				auto d = state->d;
				auto e = state->e;
				auto f = state->f;
				auto g = state->g;
				auto h = state->h;

				GenSchedule(state, M);

				for(auto t = 0; t < SHA512_ROUNDS_PER_BLOCK; t++)
				{
					auto t1 = h + SIGMA1(e) + ch(e, f, g) + K[t] + state->W[t];
					auto t2 = SIGMA0(a) + maj(a, b, c);
					h = g;
					g = f;
					f = e;
					e = d + t1;
					d = c;
					c = b;
					b = a;
					a = t1 + t2;
				}

				state->a += a;
				state->b += b;
				state->c += c;
				state->d += d;
				state->e += e;
				state->f += f;
				state->g += g;
				state->h += h;
			}

			/** Extract and pad up to 1024 bits from the buffer. If less than 112 bytes were extracted, the length field is appended after padding */
			MessageBlock ExtractAndPadBlock(const char* buff, size_t off, size_t len, size_t* realLen = nullptr)
			{
				MessageBlock result;

				// Extract as many bytes from the buffer into the block that we can
				uint64_t i = 0;
				for(; i < SHA512_BLOCK_SIZE_BYTES && (off + i) < len; i++)
				{
					result[i / 8] |= (0ull | (0xff & buff[off + i])) << ((7 - i) << 3);
				}
				// If we ran out of bytes, insert padding
				if (i < SHA512_BLOCK_SIZE_BYTES)
				{
					// A '1' bit after the message followed by zeroes
					result[i / 8] |= (0ull | 0x80) << ((7 - (i % 8)) << 3);
					if(len - off < 112)
					{
						// with the length we extracted at the end
						result[15] = (realLen != nullptr ? *realLen : len) << 3;
					}
				}

				return result;
			}

			LIBCRYPTO_PUB char* ComputeHash(const char* buff, size_t len)
			{
				auto state = new State();
				auto blocks = len / SHA512_BLOCK_SIZE_BYTES + (len % SHA512_BLOCK_SIZE_BYTES != 0 ? 1 : 0);

				if(len == 0 || (len == 1 && buff[0] == 0))
				{
					// Special case for empty string
					MessageBlock M;
					M[0] = 1ull << 63;
					round(state, M);
				}
				else
				{
					for(auto i = 0; i < blocks; i++)
					{
						auto M = ExtractAndPadBlock(buff, i * SHA512_BLOCK_SIZE_BYTES, len);
						round(state, M);
					}

					// Final padding comes after
					if(len % SHA512_BLOCK_SIZE_BYTES == 0)
					{
						// If we're exactly a multiple of 128 bytes, the first byte of the padding block needs to be set
						MessageBlock M;
						M[0] = 1ull << 63;
						M[15] = len << 3;
						round(state, M);
					}
					else if(len - (blocks - 1) * SHA512_BLOCK_SIZE_BYTES >= 112)
					{
						// Otherwise the padding bit was already set, just append the length
						MessageBlock M;
						M[15] = len << 3;
						round(state, M);
					}

				}

				auto result = new char[64]{ 0 };

				libcrypto::buffStuff64(result,  0, state->a);
				libcrypto::buffStuff64(result,  8, state->b);
				libcrypto::buffStuff64(result, 16, state->c);
				libcrypto::buffStuff64(result, 24, state->d);
				libcrypto::buffStuff64(result, 32, state->e);
				libcrypto::buffStuff64(result, 40, state->f);
				libcrypto::buffStuff64(result, 48, state->g);
				libcrypto::buffStuff64(result, 56, state->h);

				delete state;
				return result;
			}

			LIBCRYPTO_PUB char* ComputeHash(std::string str)
			{
				return ComputeHash(str.c_str(), str.length());
			}

			LIBCRYPTO_PUB void ComputePartialHash(char* prev, const char* buff, size_t len, bool initialBlock, size_t* totalLength)
			{
				if (totalLength == nullptr && len % SHA512_BLOCK_SIZE_BYTES != 0) throw std::length_error("Non-final input block must be a multiple of 128 bytes");

				auto blocks = len / SHA512_BLOCK_SIZE_BYTES + (totalLength != nullptr && len % SHA512_BLOCK_SIZE_BYTES != 0 ? 1 : 0);

				auto state = new State();
				auto previousState = reinterpret_cast<uint64_t*>(prev);

				if(!initialBlock)
				{
					state->a = _byteswap_uint64(previousState[0]);
					state->b = _byteswap_uint64(previousState[1]);
					state->c = _byteswap_uint64(previousState[2]);
					state->d = _byteswap_uint64(previousState[3]);
					state->e = _byteswap_uint64(previousState[4]);
					state->f = _byteswap_uint64(previousState[5]);
					state->g = _byteswap_uint64(previousState[6]);
					state->h = _byteswap_uint64(previousState[7]);
				}

				for(auto i = 0; i < blocks; i++)
				{
					auto M = ExtractAndPadBlock(buff, i * SHA512_BLOCK_SIZE_BYTES, len, totalLength);
					round(state, M);
				}

				if(totalLength != nullptr)
				{
					// Final padding comes after
					if(len % SHA512_BLOCK_SIZE_BYTES == 0)
					{
						// If we're exactly a multiple of 128 bytes, the first byte of the padding block needs to be set
						MessageBlock M;
						M[0] = 1ull << 63;
						M[15] = *totalLength << 3;
						round(state, M);
					}
					else if(len - (blocks - 1) * SHA512_BLOCK_SIZE_BYTES >= 112)
					{
						// Otherwise the padding bit was already set, just append the length
						MessageBlock M;
						M[15] = *totalLength << 3;
						round(state, M);
					}
				}

				previousState[0] = _byteswap_uint64(state->a);
				previousState[1] = _byteswap_uint64(state->b);
				previousState[2] = _byteswap_uint64(state->c);
				previousState[3] = _byteswap_uint64(state->d);
				previousState[4] = _byteswap_uint64(state->e);
				previousState[5] = _byteswap_uint64(state->f);
				previousState[6] = _byteswap_uint64(state->g);
				previousState[7] = _byteswap_uint64(state->h);

				delete state;
			}
		}
	}
}
<commit_msg>Use compiler intrinsics for rotr<commit_after>/*
 * Copyright (c) 2016 Nathan Lowe
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * SHA512.cpp - Implementation of SHA2 for 512-bit digests
 */

#include <stdexcept>
#include "SHA512.h"
#include "constants.h"
#include "../libcrypto.h"

/** The number of internal rounds performed on each block of data */
#define SHA512_ROUNDS_PER_BLOCK 80

namespace libcrypto
{
	namespace hashing
	{
		namespace SHA512
		{
			/** The state used across rounds of the hash */
			typedef struct
			{
				uint64_t a = 0x6a09e667f3bcc908;
				uint64_t b = 0xbb67ae8584caa73b;
				uint64_t c = 0x3c6ef372fe94f82b;
				uint64_t d = 0xa54ff53a5f1d36f1;
				uint64_t e = 0x510e527fade682d1;
				uint64_t f = 0x9b05688c2b3e6c1f;
				uint64_t g = 0x1f83d9abfb41bd6b;
				uint64_t h = 0x5be0cd19137e2179;

				uint64_t W[SHA512_ROUNDS_PER_BLOCK] = { 0 };
			}State;

			/** A 1024-bit block that SHA512 Operates on */
			typedef struct
			{
				uint64_t& operator[](size_t idx) { return M[idx]; }
				uint64_t M[16] = { 0 };
			}MessageBlock;

			/** Choose Functipn: Bit i is selected from y if it is set in x, otherwise it is selected from z */
			inline uint64_t ch(uint64_t x, uint64_t y, uint64_t z)
			{
				return (x & y) ^ (~x & z);
			}

			/** Majority Function: Bit i is set if it is set in at least two of three inputs */
			inline uint64_t maj(uint64_t x, uint64_t y, uint64_t z)
			{
				return (x & y) ^ (x & z) ^ (y & z);
			}

			/** Big-Sigma 0 from FIPS 1SHA512_ROUNDS_PER_BLOCK-4 */
			inline uint64_t SIGMA0(uint64_t x)
			{
				return _rotr64(x, 28) ^ _rotr64(x, 34) ^ _rotr64(x, 39);
			}

			/** Big-Sigma 0 from FIPS 1SHA512_ROUNDS_PER_BLOCK-4 */
			inline uint64_t SIGMA1(uint64_t x)
			{
				return _rotr64(x, 14) ^ _rotr64(x, 18) ^ _rotr64(x, 41);
			}

			/** Little-Sigma 0 from FIPS 1SHA512_ROUNDS_PER_BLOCK-4 */
			inline uint64_t sigma0(uint64_t x)
			{
				return _rotr64(x, 1) ^ _rotr64(x, 8) ^ (x >> 7);
			}

			/** Little-Sigma 1 from FIPS 1SHA512_ROUNDS_PER_BLOCK-4 */
			inline uint64_t sigma1(uint64_t x)
			{
				return _rotr64(x, 19) ^ _rotr64(x, 61) ^ (x >> 6);
			}

			/** Generate the word schedule for the round from the specified message block */
			inline void GenSchedule(State* state, MessageBlock M)
			{
				for(auto t = 0; t < 16; t++)
				{
					state->W[t] = M[t];
				}
				for(auto t = 16; t < SHA512_ROUNDS_PER_BLOCK; t++)
				{
					state->W[t] = sigma1(state->W[t - 2]) + state->W[t - 7] + sigma0(state->W[t - 15]) + state->W[t - 16];
				}
			}

			/** Perform an iteration of SHA512 on the specified message block */
			inline void round(State* state, MessageBlock M)
			{
				auto a = state->a;
				auto b = state->b;
				auto c = state->c;
				auto d = state->d;
				auto e = state->e;
				auto f = state->f;
				auto g = state->g;
				auto h = state->h;

				GenSchedule(state, M);

				for(auto t = 0; t < SHA512_ROUNDS_PER_BLOCK; t++)
				{
					auto t1 = h + SIGMA1(e) + ch(e, f, g) + K[t] + state->W[t];
					auto t2 = SIGMA0(a) + maj(a, b, c);
					h = g;
					g = f;
					f = e;
					e = d + t1;
					d = c;
					c = b;
					b = a;
					a = t1 + t2;
				}

				state->a += a;
				state->b += b;
				state->c += c;
				state->d += d;
				state->e += e;
				state->f += f;
				state->g += g;
				state->h += h;
			}

			/** Extract and pad up to 1024 bits from the buffer. If less than 112 bytes were extracted, the length field is appended after padding */
			MessageBlock ExtractAndPadBlock(const char* buff, size_t off, size_t len, size_t* realLen = nullptr)
			{
				MessageBlock result;

				// Extract as many bytes from the buffer into the block that we can
				uint64_t i = 0;
				for(; i < SHA512_BLOCK_SIZE_BYTES && (off + i) < len; i++)
				{
					result[i / 8] |= (0ull | (0xff & buff[off + i])) << ((7 - i) << 3);
				}
				// If we ran out of bytes, insert padding
				if (i < SHA512_BLOCK_SIZE_BYTES)
				{
					// A '1' bit after the message followed by zeroes
					result[i / 8] |= (0ull | 0x80) << ((7 - (i % 8)) << 3);
					if(len - off < 112)
					{
						// with the length we extracted at the end
						result[15] = (realLen != nullptr ? *realLen : len) << 3;
					}
				}

				return result;
			}

			LIBCRYPTO_PUB char* ComputeHash(const char* buff, size_t len)
			{
				auto state = new State();
				auto blocks = len / SHA512_BLOCK_SIZE_BYTES + (len % SHA512_BLOCK_SIZE_BYTES != 0 ? 1 : 0);

				if(len == 0 || (len == 1 && buff[0] == 0))
				{
					// Special case for empty string
					MessageBlock M;
					M[0] = 1ull << 63;
					round(state, M);
				}
				else
				{
					for(auto i = 0; i < blocks; i++)
					{
						auto M = ExtractAndPadBlock(buff, i * SHA512_BLOCK_SIZE_BYTES, len);
						round(state, M);
					}

					// Final padding comes after
					if(len % SHA512_BLOCK_SIZE_BYTES == 0)
					{
						// If we're exactly a multiple of 128 bytes, the first byte of the padding block needs to be set
						MessageBlock M;
						M[0] = 1ull << 63;
						M[15] = len << 3;
						round(state, M);
					}
					else if(len - (blocks - 1) * SHA512_BLOCK_SIZE_BYTES >= 112)
					{
						// Otherwise the padding bit was already set, just append the length
						MessageBlock M;
						M[15] = len << 3;
						round(state, M);
					}

				}

				auto result = new char[64]{ 0 };

				libcrypto::buffStuff64(result,  0, state->a);
				libcrypto::buffStuff64(result,  8, state->b);
				libcrypto::buffStuff64(result, 16, state->c);
				libcrypto::buffStuff64(result, 24, state->d);
				libcrypto::buffStuff64(result, 32, state->e);
				libcrypto::buffStuff64(result, 40, state->f);
				libcrypto::buffStuff64(result, 48, state->g);
				libcrypto::buffStuff64(result, 56, state->h);

				delete state;
				return result;
			}

			LIBCRYPTO_PUB char* ComputeHash(std::string str)
			{
				return ComputeHash(str.c_str(), str.length());
			}

			LIBCRYPTO_PUB void ComputePartialHash(char* prev, const char* buff, size_t len, bool initialBlock, size_t* totalLength)
			{
				if (totalLength == nullptr && len % SHA512_BLOCK_SIZE_BYTES != 0) throw std::length_error("Non-final input block must be a multiple of 128 bytes");

				auto blocks = len / SHA512_BLOCK_SIZE_BYTES + (totalLength != nullptr && len % SHA512_BLOCK_SIZE_BYTES != 0 ? 1 : 0);

				auto state = new State();
				auto previousState = reinterpret_cast<uint64_t*>(prev);

				if(!initialBlock)
				{
					state->a = _byteswap_uint64(previousState[0]);
					state->b = _byteswap_uint64(previousState[1]);
					state->c = _byteswap_uint64(previousState[2]);
					state->d = _byteswap_uint64(previousState[3]);
					state->e = _byteswap_uint64(previousState[4]);
					state->f = _byteswap_uint64(previousState[5]);
					state->g = _byteswap_uint64(previousState[6]);
					state->h = _byteswap_uint64(previousState[7]);
				}

				for(auto i = 0; i < blocks; i++)
				{
					auto M = ExtractAndPadBlock(buff, i * SHA512_BLOCK_SIZE_BYTES, len, totalLength);
					round(state, M);
				}

				if(totalLength != nullptr)
				{
					// Final padding comes after
					if(len % SHA512_BLOCK_SIZE_BYTES == 0)
					{
						// If we're exactly a multiple of 128 bytes, the first byte of the padding block needs to be set
						MessageBlock M;
						M[0] = 1ull << 63;
						M[15] = *totalLength << 3;
						round(state, M);
					}
					else if(len - (blocks - 1) * SHA512_BLOCK_SIZE_BYTES >= 112)
					{
						// Otherwise the padding bit was already set, just append the length
						MessageBlock M;
						M[15] = *totalLength << 3;
						round(state, M);
					}
				}

				previousState[0] = _byteswap_uint64(state->a);
				previousState[1] = _byteswap_uint64(state->b);
				previousState[2] = _byteswap_uint64(state->c);
				previousState[3] = _byteswap_uint64(state->d);
				previousState[4] = _byteswap_uint64(state->e);
				previousState[5] = _byteswap_uint64(state->f);
				previousState[6] = _byteswap_uint64(state->g);
				previousState[7] = _byteswap_uint64(state->h);

				delete state;
			}
		}
	}
}
<|endoftext|>


<commit_before><commit_msg>Resolved CID 351781 (Invalid type in argument to printf format specifier)<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS presentationengine01 (1.12.432); FILE MERGED 2004/11/18 13:13:14 thb 1.12.432.2: #i10000# File merged, but not committed 2004/07/05 13:10:01 cl 1.12.432.1: smile<commit_after><|endoftext|>


<commit_before>/*
    kopeteprotocol.cpp - Kopete Protocol

    Copyright (c) 2002      by Duncan Mac-Vicar Prett <duncan@kde.org>
    Copyright (c) 2002-2003 by Martijn Klingens       <klingens@kde.org>
    Copyright (c) 2002-2003 by Olivier Goffart        <ogoffart@tiscalinet.be>

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This library is free software; you can redistribute it and/or         *
    * modify it under the terms of the GNU Lesser General Public            *
    * License as published by the Free Software Foundation; either          *
    * version 2 of the License, or (at your option) any later version.      *
    *                                                                       *
    *************************************************************************
*/

#include "kopeteprotocol.h"

#include <kdebug.h>
#include <kaction.h>

#include "kopetemessagemanagerfactory.h"
#include "kopetemetacontact.h"
#include "kopeteaccountmanager.h"
#include "kopeteaccount.h"

KopeteProtocol::KopeteProtocol(QObject *parent, const char *name)
    : KopetePlugin( parent, name )
{
	// FIXME: avoid having to use an arbitrary number like 765
	// and *hope* that protocols won't declare their own KOS with
	// the same internalStatus
	m_status = KopeteOnlineStatus( KopeteOnlineStatus::Unknown, 0,
			this, 765, QString::fromLatin1( "status_unknown" )
			, QString::null, QString::null );
}

KopeteProtocol::~KopeteProtocol()
{
	// Remove all active accounts
	QDict<KopeteAccount> accounts = KopeteAccountManager::manager()->accounts( this );
	for( QDictIterator<KopeteAccount> it( accounts ); it.current() ; ++it )
		delete *it;
}

KopeteOnlineStatus KopeteProtocol::status() const
{
	return m_status;
}

KActionMenu* KopeteProtocol::protocolActions()
{
	QDict<KopeteAccount> dict=KopeteAccountManager::manager()->accounts(this);
	QDictIterator<KopeteAccount> it( dict );
	if(dict.count() == 1 )
	{
		return (it.current())->actionMenu();
	}

	KActionMenu *m_menu = new KActionMenu(displayName(),pluginIcon(),this);

	for( ; KopeteAccount *account = it.current(); ++it )
	{
		KActionMenu *accountMenu = account->actionMenu();
		if(accountMenu->parent())
			accountMenu->parent()->removeChild( accountMenu );
		m_menu->insertChild( accountMenu );
		m_menu->insert( accountMenu );
	}

	return m_menu;
}

void KopeteProtocol::slotMetaContactAboutToSave( KopeteMetaContact *metaContact )
{
	QMap<QString, QString> serializedData, sd;
	QMap<QString, QString> addressBookData, ad;
	QMap<QString, QString>::Iterator it;

//	kdDebug( 14010 ) << "KopeteProtocol::metaContactAboutToSave: protocol " << pluginId() << ": serializing " << metaContact->displayName() << endl;

	QPtrList<KopeteContact> contacts=metaContact->contacts();
	for (KopeteContact *c=contacts.first() ; c ; c=contacts.next() )
	{
		if( c->protocol()->pluginId() != pluginId() )
			continue;

		sd.clear();
		ad.clear();

		// Preset the contactId and displayName, if the plugin doesn't want to save
		// them, or use its own format, it can call clear() on the provided list
		sd[ QString::fromLatin1( "contactId" ) ] =   c->contactId();
		sd[ QString::fromLatin1( "displayName" ) ] = c->displayName();
		if(c->account())
			sd[ QString::fromLatin1( "accountId" ) ] =   c->account()->accountId();

		// If there's an index field preset it too
		QString index = c->protocol()->addressBookIndexField();
		if( !index.isEmpty() )
			ad[ index ] = c->contactId();

		c->serialize( sd, ad );

		// Merge the returned fields with what we already (may) have
		for( it = sd.begin(); it != sd.end(); ++it )
		{
			// The Unicode chars E000-F800 are non-printable and reserved for
			// private use in applications. For more details, see also
			// http://www.unicode.org/charts/PDF/UE000.pdf.
			// Inside libkabc the use of QChar( 0xE000 ) has been standardized
			// as separator for the string lists, use this also for the 'normal'
			// serialized data.
			if( serializedData.contains( it.key() ) )
				serializedData[ it.key() ] = serializedData[ it.key() ] + QChar( 0xE000 ) + it.data();
			else
				serializedData[ it.key() ] = it.data();
		}

		for( it = ad.begin(); it != ad.end(); ++it )
		{
			if( addressBookData.contains( it.key() ) )
				addressBookData[ it.key() ] = addressBookData[ it.key() ] + QChar( 0xE000 ) + it.data();
			else
				addressBookData[ it.key() ] = it.data();
		}
	}

	// Pass all returned fields to the contact list
	if( !serializedData.isEmpty() )
		metaContact->setPluginData( this, serializedData );

	for( it = addressBookData.begin(); it != addressBookData.end(); ++it )
	{
		//kdDebug( 14010 ) << "KopeteProtocol::metaContactAboutToSave: addressBookData: key: " << it.key() << ", data: " << it.data() << endl;
		// FIXME: This is a terrible hack to check the key name for the phrase "messaging/"
		//        to indicate what app name to use, but for now it's by far the easiest
		//        way to get this working.
		//        Once all this is in CVS and the actual storage in libkabc is working
		//        we can devise a better API, but with the constantly changing
		//        requirements every time I learn more about kabc I'd better no touch
		//        the API yet - Martijn
		if( it.key().startsWith( QString::fromLatin1( "messaging/" ) ) )
		{
			metaContact->setAddressBookField( this, it.key(), QString::fromLatin1( "All" ), it.data() );
//			kdDebug() << k_funcinfo << "metaContact->setAddressBookField( " << this << ", " << it.key() << ", \"All\", " << it.data() << " );" << endl;
		}
		else
			metaContact->setAddressBookField( this, QString::fromLatin1( "kopete" ), it.key(), it.data() );
	}
}

void KopeteProtocol::deserialize( KopeteMetaContact *metaContact, const QMap<QString, QString> &data )
{
	//kdDebug( 14010 ) << "KopeteProtocol::deserialize: protocol " << pluginId() << ": deserializing " << metaContact->displayName() << endl;

	QMap<QString, QStringList> serializedData;
	QMap<QString, QStringList::Iterator> serializedDataIterators;
	QMap<QString, QString>::ConstIterator it;
	for( it = data.begin(); it != data.end(); ++it )
	{
		serializedData[ it.key() ] = QStringList::split( QChar( 0xE000 ), it.data(), true );
		serializedDataIterators[ it.key() ] = serializedData[ it.key() ].begin();
	}

	uint count = serializedData[QString::fromLatin1("contactId")].count();

	// Prepare the independent entries to pass to the plugin's implementation
	for( uint i = 0; i < count ; i++ )
	{
		QMap<QString, QString> sd;
		QMap<QString, QStringList::Iterator>::Iterator serializedDataIt;
		for( serializedDataIt = serializedDataIterators.begin(); serializedDataIt != serializedDataIterators.end(); ++serializedDataIt )
		{
			sd[ serializedDataIt.key() ] = *( serializedDataIt.data() );
			++( serializedDataIt.data() );
		}

		// FIXME: This code almost certainly breaks when having more than
		//        one contact in a meta contact. There are solutions, but
		//        they are all hacky and the API needs revision anyway (see
		//        FIXME a few lines below :), so I'm not going to add that
		//        for now.
		//        Note that even though it breaks, the current code will
		//        never notice, since none of the plugins use the address
		//        book data in the deserializer yet, only when serializing.
		//        - Martijn
		QMap<QString, QString> ad;
		QStringList kabcFields = addressBookFields();
		for( QStringList::Iterator fieldIt = kabcFields.begin(); fieldIt != kabcFields.end(); ++fieldIt )
		{
			// FIXME: This hack is even more ugly, and has the same reasons as the similar
			//        hack in the serialize code.
			//        Once this code is actually capable of talking to kabc this hack
			//        should be removed ASAP! - Martijn
			if( ( *fieldIt ).startsWith( QString::fromLatin1( "messaging/" ) ) )
				ad[ *fieldIt ] = metaContact->addressBookField( this, *fieldIt, QString::fromLatin1( "All" ) );
			else
				ad[ *fieldIt ] = metaContact->addressBookField( this, QString::fromLatin1( "kopete" ), *fieldIt );
		}

		deserializeContact( metaContact, sd, ad );
	}
}

void KopeteProtocol::deserializeContact( KopeteMetaContact * /* metaContact */, const QMap<QString, QString> & /* serializedData */,
	const QMap<QString, QString> & /* addressBookData */ )
{
	/* Default implementation does nothing */
}

void KopeteProtocol::slotAccountAdded()
{
	QDict<KopeteAccount> dict=KopeteAccountManager::manager()->accounts(this);
	QDictIterator<KopeteAccount> it( dict );
	for( ; KopeteAccount *account=it.current(); ++it )
	{
		if(account->myself())
		{	//because we can't know if the account has already connected
			QObject::disconnect(account->myself() , SIGNAL(onlineStatusChanged( KopeteContact *, const KopeteOnlineStatus &, const KopeteOnlineStatus & )) , this , SLOT( slotRefreshStatus()));
			QObject::connect   (account->myself() , SIGNAL(onlineStatusChanged( KopeteContact *, const KopeteOnlineStatus &, const KopeteOnlineStatus & )) , this , SLOT( slotRefreshStatus()));
		}
	}
	slotRefreshStatus();
}

void KopeteProtocol::slotRefreshStatus()
{
	KopeteOnlineStatus newStatus;
	QDict<KopeteAccount> dict=KopeteAccountManager::manager()->accounts(this);
	QDictIterator<KopeteAccount> it( dict );

	bool accountsFound = false;
	for( ; KopeteAccount *account = it.current(); ++it )
	{
		accountsFound = true;
		if(account->myself())
		{
			if(account->myself()->onlineStatus() > newStatus)
			{
				newStatus = account->myself()->onlineStatus();
			}
		}
	}

	if ( !accountsFound )
		newStatus = KopeteOnlineStatus( KopeteOnlineStatus::Unknown, 0,
			this, 765, QString::fromLatin1( "status_unknown" ),
			QString::null, QString::null );

	if( newStatus != m_status )
	{
		m_status = newStatus;
		emit( statusIconChanged( m_status ) );
	}
}

#include "kopeteprotocol.moc"

// vim: set noet ts=4 sts=4 sw=4:

<commit_msg>My previous commit in KopeteContact was not complete. now, moving to another matacontact should works<commit_after>/*
    kopeteprotocol.cpp - Kopete Protocol

    Copyright (c) 2002      by Duncan Mac-Vicar Prett <duncan@kde.org>
    Copyright (c) 2002-2003 by Martijn Klingens       <klingens@kde.org>
    Copyright (c) 2002-2003 by Olivier Goffart        <ogoffart@tiscalinet.be>

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This library is free software; you can redistribute it and/or         *
    * modify it under the terms of the GNU Lesser General Public            *
    * License as published by the Free Software Foundation; either          *
    * version 2 of the License, or (at your option) any later version.      *
    *                                                                       *
    *************************************************************************
*/

#include "kopeteprotocol.h"

#include <kdebug.h>
#include <kaction.h>

#include "kopetemessagemanagerfactory.h"
#include "kopetemetacontact.h"
#include "kopeteaccountmanager.h"
#include "kopeteaccount.h"

KopeteProtocol::KopeteProtocol(QObject *parent, const char *name)
    : KopetePlugin( parent, name )
{
	// FIXME: avoid having to use an arbitrary number like 765
	// and *hope* that protocols won't declare their own KOS with
	// the same internalStatus
	m_status = KopeteOnlineStatus( KopeteOnlineStatus::Unknown, 0,
			this, 765, QString::fromLatin1( "status_unknown" )
			, QString::null, QString::null );
}

KopeteProtocol::~KopeteProtocol()
{
	// Remove all active accounts
	QDict<KopeteAccount> accounts = KopeteAccountManager::manager()->accounts( this );
	for( QDictIterator<KopeteAccount> it( accounts ); it.current() ; ++it )
		delete *it;
}

KopeteOnlineStatus KopeteProtocol::status() const
{
	return m_status;
}

KActionMenu* KopeteProtocol::protocolActions()
{
	QDict<KopeteAccount> dict=KopeteAccountManager::manager()->accounts(this);
	QDictIterator<KopeteAccount> it( dict );
	if(dict.count() == 1 )
	{
		return (it.current())->actionMenu();
	}

	KActionMenu *m_menu = new KActionMenu(displayName(),pluginIcon(),this);

	for( ; KopeteAccount *account = it.current(); ++it )
	{
		KActionMenu *accountMenu = account->actionMenu();
		if(accountMenu->parent())
			accountMenu->parent()->removeChild( accountMenu );
		m_menu->insertChild( accountMenu );
		m_menu->insert( accountMenu );
	}

	return m_menu;
}

void KopeteProtocol::slotMetaContactAboutToSave( KopeteMetaContact *metaContact )
{
	QMap<QString, QString> serializedData, sd;
	QMap<QString, QString> addressBookData, ad;
	QMap<QString, QString>::Iterator it;

//	kdDebug( 14010 ) << "KopeteProtocol::metaContactAboutToSave: protocol " << pluginId() << ": serializing " << metaContact->displayName() << endl;

	QPtrList<KopeteContact> contacts=metaContact->contacts();
	for (KopeteContact *c=contacts.first() ; c ; c=contacts.next() )
	{
		if( c->protocol()->pluginId() != pluginId() )
			continue;

		sd.clear();
		ad.clear();

		// Preset the contactId and displayName, if the plugin doesn't want to save
		// them, or use its own format, it can call clear() on the provided list
		sd[ QString::fromLatin1( "contactId" ) ] =   c->contactId();
		sd[ QString::fromLatin1( "displayName" ) ] = c->displayName();
		if(c->account())
			sd[ QString::fromLatin1( "accountId" ) ] =   c->account()->accountId();

		// If there's an index field preset it too
		QString index = c->protocol()->addressBookIndexField();
		if( !index.isEmpty() )
			ad[ index ] = c->contactId();

		c->serialize( sd, ad );

		// Merge the returned fields with what we already (may) have
		for( it = sd.begin(); it != sd.end(); ++it )
		{
			// The Unicode chars E000-F800 are non-printable and reserved for
			// private use in applications. For more details, see also
			// http://www.unicode.org/charts/PDF/UE000.pdf.
			// Inside libkabc the use of QChar( 0xE000 ) has been standardized
			// as separator for the string lists, use this also for the 'normal'
			// serialized data.
			if( serializedData.contains( it.key() ) )
				serializedData[ it.key() ] = serializedData[ it.key() ] + QChar( 0xE000 ) + it.data();
			else
				serializedData[ it.key() ] = it.data();
		}

		for( it = ad.begin(); it != ad.end(); ++it )
		{
			if( addressBookData.contains( it.key() ) )
				addressBookData[ it.key() ] = addressBookData[ it.key() ] + QChar( 0xE000 ) + it.data();
			else
				addressBookData[ it.key() ] = it.data();
		}
	}

	// Pass all returned fields to the contact list
	//if( !serializedData.isEmpty() ) //even if we are empty, that mean there are no contact, so remove old value
	metaContact->setPluginData( this, serializedData );

	for( it = addressBookData.begin(); it != addressBookData.end(); ++it )
	{
		//kdDebug( 14010 ) << "KopeteProtocol::metaContactAboutToSave: addressBookData: key: " << it.key() << ", data: " << it.data() << endl;
		// FIXME: This is a terrible hack to check the key name for the phrase "messaging/"
		//        to indicate what app name to use, but for now it's by far the easiest
		//        way to get this working.
		//        Once all this is in CVS and the actual storage in libkabc is working
		//        we can devise a better API, but with the constantly changing
		//        requirements every time I learn more about kabc I'd better no touch
		//        the API yet - Martijn
		if( it.key().startsWith( QString::fromLatin1( "messaging/" ) ) )
		{
			metaContact->setAddressBookField( this, it.key(), QString::fromLatin1( "All" ), it.data() );
//			kdDebug() << k_funcinfo << "metaContact->setAddressBookField( " << this << ", " << it.key() << ", \"All\", " << it.data() << " );" << endl;
		}
		else
			metaContact->setAddressBookField( this, QString::fromLatin1( "kopete" ), it.key(), it.data() );
	}
}

void KopeteProtocol::deserialize( KopeteMetaContact *metaContact, const QMap<QString, QString> &data )
{
	//kdDebug( 14010 ) << "KopeteProtocol::deserialize: protocol " << pluginId() << ": deserializing " << metaContact->displayName() << endl;

	QMap<QString, QStringList> serializedData;
	QMap<QString, QStringList::Iterator> serializedDataIterators;
	QMap<QString, QString>::ConstIterator it;
	for( it = data.begin(); it != data.end(); ++it )
	{
		serializedData[ it.key() ] = QStringList::split( QChar( 0xE000 ), it.data(), true );
		serializedDataIterators[ it.key() ] = serializedData[ it.key() ].begin();
	}

	uint count = serializedData[QString::fromLatin1("contactId")].count();

	// Prepare the independent entries to pass to the plugin's implementation
	for( uint i = 0; i < count ; i++ )
	{
		QMap<QString, QString> sd;
		QMap<QString, QStringList::Iterator>::Iterator serializedDataIt;
		for( serializedDataIt = serializedDataIterators.begin(); serializedDataIt != serializedDataIterators.end(); ++serializedDataIt )
		{
			sd[ serializedDataIt.key() ] = *( serializedDataIt.data() );
			++( serializedDataIt.data() );
		}

		// FIXME: This code almost certainly breaks when having more than
		//        one contact in a meta contact. There are solutions, but
		//        they are all hacky and the API needs revision anyway (see
		//        FIXME a few lines below :), so I'm not going to add that
		//        for now.
		//        Note that even though it breaks, the current code will
		//        never notice, since none of the plugins use the address
		//        book data in the deserializer yet, only when serializing.
		//        - Martijn
		QMap<QString, QString> ad;
		QStringList kabcFields = addressBookFields();
		for( QStringList::Iterator fieldIt = kabcFields.begin(); fieldIt != kabcFields.end(); ++fieldIt )
		{
			// FIXME: This hack is even more ugly, and has the same reasons as the similar
			//        hack in the serialize code.
			//        Once this code is actually capable of talking to kabc this hack
			//        should be removed ASAP! - Martijn
			if( ( *fieldIt ).startsWith( QString::fromLatin1( "messaging/" ) ) )
				ad[ *fieldIt ] = metaContact->addressBookField( this, *fieldIt, QString::fromLatin1( "All" ) );
			else
				ad[ *fieldIt ] = metaContact->addressBookField( this, QString::fromLatin1( "kopete" ), *fieldIt );
		}

		deserializeContact( metaContact, sd, ad );
	}
}

void KopeteProtocol::deserializeContact( KopeteMetaContact * /* metaContact */, const QMap<QString, QString> & /* serializedData */,
	const QMap<QString, QString> & /* addressBookData */ )
{
	/* Default implementation does nothing */
}

void KopeteProtocol::slotAccountAdded()
{
	QDict<KopeteAccount> dict=KopeteAccountManager::manager()->accounts(this);
	QDictIterator<KopeteAccount> it( dict );
	for( ; KopeteAccount *account=it.current(); ++it )
	{
		if(account->myself())
		{	//because we can't know if the account has already connected
			QObject::disconnect(account->myself() , SIGNAL(onlineStatusChanged( KopeteContact *, const KopeteOnlineStatus &, const KopeteOnlineStatus & )) , this , SLOT( slotRefreshStatus()));
			QObject::connect   (account->myself() , SIGNAL(onlineStatusChanged( KopeteContact *, const KopeteOnlineStatus &, const KopeteOnlineStatus & )) , this , SLOT( slotRefreshStatus()));
		}
	}
	slotRefreshStatus();
}

void KopeteProtocol::slotRefreshStatus()
{
	KopeteOnlineStatus newStatus;
	QDict<KopeteAccount> dict=KopeteAccountManager::manager()->accounts(this);
	QDictIterator<KopeteAccount> it( dict );

	bool accountsFound = false;
	for( ; KopeteAccount *account = it.current(); ++it )
	{
		accountsFound = true;
		if(account->myself())
		{
			if(account->myself()->onlineStatus() > newStatus)
			{
				newStatus = account->myself()->onlineStatus();
			}
		}
	}

	if ( !accountsFound )
		newStatus = KopeteOnlineStatus( KopeteOnlineStatus::Unknown, 0,
			this, 765, QString::fromLatin1( "status_unknown" ),
			QString::null, QString::null );

	if( newStatus != m_status )
	{
		m_status = newStatus;
		emit( statusIconChanged( m_status ) );
	}
}

#include "kopeteprotocol.moc"

// vim: set noet ts=4 sts=4 sw=4:

<|endoftext|>


<commit_before>// Copyright 2015 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

// +build

#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#define SYZ_EXECUTOR
#include "common_linux.h"

#include "executor_linux.h"

#include "executor.h"

#include "syscalls_linux.h"

#define KCOV_INIT_TRACE32 _IOR('c', 1, uint32)
#define KCOV_INIT_TRACE64 _IOR('c', 1, uint64)
#define KCOV_ENABLE _IO('c', 100)
#define KCOV_DISABLE _IO('c', 101)

const unsigned long KCOV_TRACE_PC = 0;
const unsigned long KCOV_TRACE_CMP = 1;

const int kInFd = 3;
const int kOutFd = 4;

uint32* output_data;
uint32* output_pos;

static bool detect_kernel_bitness();

int main(int argc, char** argv)
{
	is_kernel_64_bit = detect_kernel_bitness();
	if (argc == 2 && strcmp(argv[1], "version") == 0) {
		puts(GOOS " " GOARCH " " SYZ_REVISION " " GIT_REVISION);
		return 0;
	}

	prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
	if (mmap(&input_data[0], kMaxInput, PROT_READ, MAP_PRIVATE | MAP_FIXED, kInFd, 0) != &input_data[0])
		fail("mmap of input file failed");
	// The output region is the only thing in executor process for which consistency matters.
	// If it is corrupted ipc package will fail to parse its contents and panic.
	// But fuzzer constantly invents new ways of how to currupt the region,
	// so we map the region at a (hopefully) hard to guess address with random offset,
	// surrounded by unmapped pages.
	// The address chosen must also work on 32-bit kernels with 1GB user address space.
	void* preferred = (void*)(0x1b2bc20000ull + (1 << 20) * (getpid() % 128));
	output_data = (uint32*)mmap(preferred, kMaxOutput,
				    PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, kOutFd, 0);
	if (output_data != preferred)
		fail("mmap of output file failed");
	if (mmap((void*)SYZ_DATA_OFFSET, SYZ_NUM_PAGES * SYZ_PAGE_SIZE, PROT_READ | PROT_WRITE,
		 MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0) != (void*)SYZ_DATA_OFFSET)
		fail("mmap of data segment failed");
	// Prevent random programs to mess with these fds.
	// Due to races in collider mode, a program can e.g. ftruncate one of these fds,
	// which will cause fuzzer to crash.
	// That's also the reason why we close kInPipeFd/kOutPipeFd below.
	close(kInFd);
	close(kOutFd);
	setup_control_pipes();
	receive_handshake();

	cover_open();
	install_segv_handler();
	use_temporary_dir();

	int pid = -1;
	switch (flag_sandbox) {
	case sandbox_none:
		pid = do_sandbox_none();
		break;
	case sandbox_setuid:
		pid = do_sandbox_setuid();
		break;
	case sandbox_namespace:
		pid = do_sandbox_namespace();
		break;
	default:
		fail("unknown sandbox type");
	}
	if (pid < 0)
		fail("clone failed");
	debug("spawned loop pid %d\n", pid);
	int status = 0;
	while (waitpid(-1, &status, __WALL) != pid) {
	}
	status = WEXITSTATUS(status);
	// Other statuses happen when fuzzer processes manages to kill loop.
	if (status != kFailStatus && status != kErrorStatus)
		status = kRetryStatus;
	// If an external sandbox process wraps executor, the out pipe will be closed
	// before the sandbox process exits this will make ipc package kill the sandbox.
	// As the result sandbox process will exit with exit status 9 instead of the executor
	// exit status (notably kRetryStatus). Consequently, ipc will treat it as hard
	// failure rather than a temporal failure. So we duplicate the exit status on the pipe.
	reply_execute(status);
	errno = 0;
	if (status == kFailStatus)
		fail("loop failed");
	if (status == kErrorStatus)
		error("loop errored");
	// Loop can be killed by a test process with e.g.:
	// ptrace(PTRACE_SEIZE, 1, 0, 0x100040)
	// This is unfortunate, but I don't have a better solution than ignoring it for now.
	exitf("loop exited with status %d", status);
	// Unreachable.
	return 1;
}

static __thread thread_t* current_thread;

long execute_syscall(call_t* c, long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8)
{
	if (c->call)
		return c->call(a0, a1, a2, a3, a4, a5, a6, a7, a8);
	return syscall(c->sys_nr, a0, a1, a2, a3, a4, a5);
}

void cover_open()
{
	if (!flag_cover)
		return;
	for (int i = 0; i < kMaxThreads; i++) {
		thread_t* th = &threads[i];
		th->cover_fd = open("/sys/kernel/debug/kcov", O_RDWR);
		if (th->cover_fd == -1)
			fail("open of /sys/kernel/debug/kcov failed");
		const int kcov_init_trace = is_kernel_64_bit ? KCOV_INIT_TRACE64 : KCOV_INIT_TRACE32;
		if (ioctl(th->cover_fd, kcov_init_trace, kCoverSize))
			fail("cover init trace write failed");
		size_t mmap_alloc_size = kCoverSize * (is_kernel_64_bit ? 8 : 4);
		th->cover_data = (char*)mmap(NULL, mmap_alloc_size, PROT_READ, MAP_SHARED, th->cover_fd, 0);
		th->cover_end = th->cover_data + mmap_alloc_size;
		if (th->cover_data == MAP_FAILED)
			fail("cover mmap failed");
		// We only write to the first page, so protect the rest from fuzzer.
		if (mprotect(th->cover_data, SYZ_PAGE_SIZE, PROT_READ | PROT_WRITE))
			fail("cover mprotect failed");
	}
}

void cover_enable(thread_t* th)
{
	if (!flag_cover)
		return;
	debug("#%d: enabling /sys/kernel/debug/kcov\n", th->id);
	int kcov_mode = flag_collect_comps ? KCOV_TRACE_CMP : KCOV_TRACE_PC;
	// This should be fatal,
	// but in practice ioctl fails with assorted errors (9, 14, 25),
	// so we use exitf.
	if (ioctl(th->cover_fd, KCOV_ENABLE, kcov_mode))
		exitf("cover enable write trace failed, mode=%d", kcov_mode);
	debug("#%d: enabled /sys/kernel/debug/kcov\n", th->id);
	current_thread = th;
}

void cover_reset(thread_t* th)
{
	if (!flag_cover)
		return;
	if (th == 0)
		th = current_thread;
	*(uint64*)th->cover_data = 0;
}

uint32 read_cover_size(thread_t* th)
{
	if (!flag_cover)
		return 0;
	// Note: this assumes little-endian kernel.
	uint32 n = *(uint32*)th->cover_data;
	debug("#%d: read cover size = %u\n", th->id, n);
	if (n >= kCoverSize)
		fail("#%d: too much cover %u", th->id, n);
	return n;
}

bool cover_check(uint32 pc)
{
	return true;
}

bool cover_check(uint64 pc)
{
#if defined(__i386__) || defined(__x86_64__)
	// Text/modules range for x86_64.
	// This causes very significant drop in corpus size. Needs additional debugging.
	// return pc >= 0xffffffff80000000ull && pc < 0xffffffffff000000ull;
	return true;
#else
	return true;
#endif
}

uint32* write_output(uint32 v)
{
	if (collide)
		return 0;
	if (output_pos < output_data || (char*)output_pos >= (char*)output_data + kMaxOutput)
		fail("output overflow");
	*output_pos = v;
	return output_pos++;
}

void write_completed(uint32 completed)
{
	__atomic_store_n(output_data, completed, __ATOMIC_RELEASE);
}

bool kcov_comparison_t::ignore() const
{
	// Comparisons with 0 are not interesting, fuzzer should be able to guess 0's without help.
	if (arg1 == 0 && (arg2 == 0 || (type & KCOV_CMP_CONST)))
		return true;
	if ((type & KCOV_CMP_SIZE_MASK) == KCOV_CMP_SIZE8) {
		// This can be a pointer (assuming 64-bit kernel).
		// First of all, we want avert fuzzer from our output region.
		// Without this fuzzer manages to discover and corrupt it.
		uint64 out_start = (uint64)output_data;
		uint64 out_end = out_start + kMaxOutput;
		if (arg1 >= out_start && arg1 <= out_end)
			return true;
		if (arg2 >= out_start && arg2 <= out_end)
			return true;
#if defined(__i386__) || defined(__x86_64__)
		// Filter out kernel physical memory addresses.
		// These are internal kernel comparisons and should not be interesting.
		// The range covers first 1TB of physical mapping.
		uint64 kmem_start = (uint64)0xffff880000000000ull;
		uint64 kmem_end = (uint64)0xffff890000000000ull;
		bool kptr1 = arg1 >= kmem_start && arg1 <= kmem_end;
		bool kptr2 = arg2 >= kmem_start && arg2 <= kmem_end;
		if (kptr1 && kptr2)
			return true;
		if (kptr1 && arg2 == 0)
			return true;
		if (kptr2 && arg1 == 0)
			return true;
#endif
	}
	return false;
}

static bool detect_kernel_bitness()
{
	if (sizeof(void*) == 8)
		return true;
	// It turns out to be surprisingly hard to understand if the kernel underneath is 64-bits.
	// A common method is to look at uname.machine. But it is produced in some involved ways,
	// and we will need to know about all strings it returns and in the end it can be overriden
	// during build and lie (and there are known precedents of this).
	// So instead we look at size of addresses in /proc/kallsyms.
	bool wide = true;
	int fd = open("/proc/kallsyms", O_RDONLY);
	if (fd != -1) {
		char buf[16];
		if (read(fd, buf, sizeof(buf)) == sizeof(buf) &&
		    (buf[8] == ' ' || buf[8] == '\t'))
			wide = false;
		close(fd);
	}
	debug("detected %d-bit kernel\n", wide ? 64 : 32);
	return wide;
}
<commit_msg>executor: revert protection of kcov region<commit_after>// Copyright 2015 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

// +build

#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#define SYZ_EXECUTOR
#include "common_linux.h"

#include "executor_linux.h"

#include "executor.h"

#include "syscalls_linux.h"

#define KCOV_INIT_TRACE32 _IOR('c', 1, uint32)
#define KCOV_INIT_TRACE64 _IOR('c', 1, uint64)
#define KCOV_ENABLE _IO('c', 100)
#define KCOV_DISABLE _IO('c', 101)

const unsigned long KCOV_TRACE_PC = 0;
const unsigned long KCOV_TRACE_CMP = 1;

const int kInFd = 3;
const int kOutFd = 4;

uint32* output_data;
uint32* output_pos;

static bool detect_kernel_bitness();

int main(int argc, char** argv)
{
	is_kernel_64_bit = detect_kernel_bitness();
	if (argc == 2 && strcmp(argv[1], "version") == 0) {
		puts(GOOS " " GOARCH " " SYZ_REVISION " " GIT_REVISION);
		return 0;
	}

	prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
	if (mmap(&input_data[0], kMaxInput, PROT_READ, MAP_PRIVATE | MAP_FIXED, kInFd, 0) != &input_data[0])
		fail("mmap of input file failed");
	// The output region is the only thing in executor process for which consistency matters.
	// If it is corrupted ipc package will fail to parse its contents and panic.
	// But fuzzer constantly invents new ways of how to currupt the region,
	// so we map the region at a (hopefully) hard to guess address with random offset,
	// surrounded by unmapped pages.
	// The address chosen must also work on 32-bit kernels with 1GB user address space.
	void* preferred = (void*)(0x1b2bc20000ull + (1 << 20) * (getpid() % 128));
	output_data = (uint32*)mmap(preferred, kMaxOutput,
				    PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, kOutFd, 0);
	if (output_data != preferred)
		fail("mmap of output file failed");
	if (mmap((void*)SYZ_DATA_OFFSET, SYZ_NUM_PAGES * SYZ_PAGE_SIZE, PROT_READ | PROT_WRITE,
		 MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0) != (void*)SYZ_DATA_OFFSET)
		fail("mmap of data segment failed");
	// Prevent random programs to mess with these fds.
	// Due to races in collider mode, a program can e.g. ftruncate one of these fds,
	// which will cause fuzzer to crash.
	// That's also the reason why we close kInPipeFd/kOutPipeFd below.
	close(kInFd);
	close(kOutFd);
	setup_control_pipes();
	receive_handshake();

	cover_open();
	install_segv_handler();
	use_temporary_dir();

	int pid = -1;
	switch (flag_sandbox) {
	case sandbox_none:
		pid = do_sandbox_none();
		break;
	case sandbox_setuid:
		pid = do_sandbox_setuid();
		break;
	case sandbox_namespace:
		pid = do_sandbox_namespace();
		break;
	default:
		fail("unknown sandbox type");
	}
	if (pid < 0)
		fail("clone failed");
	debug("spawned loop pid %d\n", pid);
	int status = 0;
	while (waitpid(-1, &status, __WALL) != pid) {
	}
	status = WEXITSTATUS(status);
	// Other statuses happen when fuzzer processes manages to kill loop.
	if (status != kFailStatus && status != kErrorStatus)
		status = kRetryStatus;
	// If an external sandbox process wraps executor, the out pipe will be closed
	// before the sandbox process exits this will make ipc package kill the sandbox.
	// As the result sandbox process will exit with exit status 9 instead of the executor
	// exit status (notably kRetryStatus). Consequently, ipc will treat it as hard
	// failure rather than a temporal failure. So we duplicate the exit status on the pipe.
	reply_execute(status);
	errno = 0;
	if (status == kFailStatus)
		fail("loop failed");
	if (status == kErrorStatus)
		error("loop errored");
	// Loop can be killed by a test process with e.g.:
	// ptrace(PTRACE_SEIZE, 1, 0, 0x100040)
	// This is unfortunate, but I don't have a better solution than ignoring it for now.
	exitf("loop exited with status %d", status);
	// Unreachable.
	return 1;
}

static __thread thread_t* current_thread;

long execute_syscall(call_t* c, long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8)
{
	if (c->call)
		return c->call(a0, a1, a2, a3, a4, a5, a6, a7, a8);
	return syscall(c->sys_nr, a0, a1, a2, a3, a4, a5);
}

void cover_open()
{
	if (!flag_cover)
		return;
	for (int i = 0; i < kMaxThreads; i++) {
		thread_t* th = &threads[i];
		th->cover_fd = open("/sys/kernel/debug/kcov", O_RDWR);
		if (th->cover_fd == -1)
			fail("open of /sys/kernel/debug/kcov failed");
		const int kcov_init_trace = is_kernel_64_bit ? KCOV_INIT_TRACE64 : KCOV_INIT_TRACE32;
		if (ioctl(th->cover_fd, kcov_init_trace, kCoverSize))
			fail("cover init trace write failed");
		size_t mmap_alloc_size = kCoverSize * (is_kernel_64_bit ? 8 : 4);
		th->cover_data = (char*)mmap(NULL, mmap_alloc_size,
					     PROT_READ | PROT_WRITE, MAP_SHARED, th->cover_fd, 0);
		th->cover_end = th->cover_data + mmap_alloc_size;
		if (th->cover_data == MAP_FAILED)
			fail("cover mmap failed");
	}
}

void cover_enable(thread_t* th)
{
	if (!flag_cover)
		return;
	debug("#%d: enabling /sys/kernel/debug/kcov\n", th->id);
	int kcov_mode = flag_collect_comps ? KCOV_TRACE_CMP : KCOV_TRACE_PC;
	// This should be fatal,
	// but in practice ioctl fails with assorted errors (9, 14, 25),
	// so we use exitf.
	if (ioctl(th->cover_fd, KCOV_ENABLE, kcov_mode))
		exitf("cover enable write trace failed, mode=%d", kcov_mode);
	debug("#%d: enabled /sys/kernel/debug/kcov\n", th->id);
	current_thread = th;
}

void cover_reset(thread_t* th)
{
	if (!flag_cover)
		return;
	if (th == 0)
		th = current_thread;
	*(uint64*)th->cover_data = 0;
}

uint32 read_cover_size(thread_t* th)
{
	if (!flag_cover)
		return 0;
	// Note: this assumes little-endian kernel.
	uint32 n = *(uint32*)th->cover_data;
	debug("#%d: read cover size = %u\n", th->id, n);
	if (n >= kCoverSize)
		fail("#%d: too much cover %u", th->id, n);
	return n;
}

bool cover_check(uint32 pc)
{
	return true;
}

bool cover_check(uint64 pc)
{
#if defined(__i386__) || defined(__x86_64__)
	// Text/modules range for x86_64.
	return pc >= 0xffffffff80000000ull && pc < 0xffffffffff000000ull;
#else
	return true;
#endif
}

uint32* write_output(uint32 v)
{
	if (collide)
		return 0;
	if (output_pos < output_data || (char*)output_pos >= (char*)output_data + kMaxOutput)
		fail("output overflow");
	*output_pos = v;
	return output_pos++;
}

void write_completed(uint32 completed)
{
	__atomic_store_n(output_data, completed, __ATOMIC_RELEASE);
}

bool kcov_comparison_t::ignore() const
{
	// Comparisons with 0 are not interesting, fuzzer should be able to guess 0's without help.
	if (arg1 == 0 && (arg2 == 0 || (type & KCOV_CMP_CONST)))
		return true;
	if ((type & KCOV_CMP_SIZE_MASK) == KCOV_CMP_SIZE8) {
		// This can be a pointer (assuming 64-bit kernel).
		// First of all, we want avert fuzzer from our output region.
		// Without this fuzzer manages to discover and corrupt it.
		uint64 out_start = (uint64)output_data;
		uint64 out_end = out_start + kMaxOutput;
		if (arg1 >= out_start && arg1 <= out_end)
			return true;
		if (arg2 >= out_start && arg2 <= out_end)
			return true;
#if defined(__i386__) || defined(__x86_64__)
		// Filter out kernel physical memory addresses.
		// These are internal kernel comparisons and should not be interesting.
		// The range covers first 1TB of physical mapping.
		uint64 kmem_start = (uint64)0xffff880000000000ull;
		uint64 kmem_end = (uint64)0xffff890000000000ull;
		bool kptr1 = arg1 >= kmem_start && arg1 <= kmem_end;
		bool kptr2 = arg2 >= kmem_start && arg2 <= kmem_end;
		if (kptr1 && kptr2)
			return true;
		if (kptr1 && arg2 == 0)
			return true;
		if (kptr2 && arg1 == 0)
			return true;
#endif
	}
	return false;
}

static bool detect_kernel_bitness()
{
	if (sizeof(void*) == 8)
		return true;
	// It turns out to be surprisingly hard to understand if the kernel underneath is 64-bits.
	// A common method is to look at uname.machine. But it is produced in some involved ways,
	// and we will need to know about all strings it returns and in the end it can be overriden
	// during build and lie (and there are known precedents of this).
	// So instead we look at size of addresses in /proc/kallsyms.
	bool wide = true;
	int fd = open("/proc/kallsyms", O_RDONLY);
	if (fd != -1) {
		char buf[16];
		if (read(fd, buf, sizeof(buf)) == sizeof(buf) &&
		    (buf[8] == ' ' || buf[8] == '\t'))
			wide = false;
		close(fd);
	}
	debug("detected %d-bit kernel\n", wide ? 64 : 32);
	return wide;
}
<|endoftext|>


<commit_before>/*
 * TTModular Library
 * Copyright © 2010, Théo de la Hogue
 *
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTModular.h"

// Statics and Globals
static bool TTModularHasInitialized = false;

TTApplicationManagerPtr	TTModularApplications = NULL;

TTHashPtr TTModularNamespaces = NULL;

/****************************************************************************************************/

void TTModularInit()
{
	// Initialized Foundation framework
	TTFoundationInit();

	// DEBUG
	TTObjectPtr test;
	TTValue v;
	TTObjectInstantiate(TT("nodelib.test"), &test, kTTValNONE);
	//test->test(v);

	if (!TTModularHasInitialized) {

		TTModularHasInitialized = true;

		// register classes -- both internal and external
		TTApplication::registerClass();
		TTApplicationManager::registerClass();
		TTContainer::registerClass();
		TTCue::registerClass();
		TTCueManager::registerClass();
		TTData::registerClass();
		TTExplorer::registerClass();
		TTInput::registerClass();
		TTMapper::registerClass();
		TTMapperManager::registerClass();
		TTMirror::registerClass();
		TTOpmlHandler::registerClass();
		TTOutput::registerClass();
		TTPreset::registerClass();
		TTPresetManager::registerClass();
		TTReceiver::registerClass();
		TTSender::registerClass();
		TTScript::registerClass();
		TTSubscriber::registerClass();
		TTTextHandler::registerClass();
		TTViewer::registerClass();
		TTXmlHandler::registerClass();

		TTModularSymbolCacheInit();
		//TTModularValueCacheInit();

		// to - this a very strange bug : the two first toString() parsing on number failed !?!
		// so here are two parsing to avoid this strange bug for instant ...
		TTString s;
		TTValue v;

		s = "0.001";
		v = s;
		v.fromString();

		v.clear();
		s = "1";
		v = s;
		v.fromString();

		// Create the Modular application manager with no application inside
		TTObjectInstantiate(kTTSym_ApplicationManager, TTObjectHandle(&TTModularApplications), kTTValNONE);

		// Create a hash table to manage namespace selections
		TTModularNamespaces = new TTHash();

#ifdef TT_DEBUG
		TTLogMessage("Modular -- Version %s -- Debugging Enabled\n", TTMODULAR_VERSION_STRING);
#else
		TTLogMessage("Modular -- Version %s\n", TTMODULAR_VERSION_STRING);
#endif

	}
}

void TTModularCreateLocalApplication(TTString applicationStr, TTString xmlConfigFilePath)
{
	TTValue				args;
	TTApplicationPtr	anApplication = NULL;

	if (TTModularApplications) {

		// if the local application doesn't exist yet
		if (!getLocalApplication) {

			// create the application
			args = TTValue(TT(applicationStr.data()));
			TTObjectInstantiate(kTTSym_Application, TTObjectHandle(&anApplication), args);

			// set it as local application
			args = TTValue((TTPtr)anApplication);
			TTModularApplications->setAttributeValue(TT("localApplication"), args);

			// Read xml configuration file
			TTXmlHandlerPtr anXmlHandler = NULL;
			TTObjectInstantiate(kTTSym_XmlHandler, TTObjectHandle(&anXmlHandler), kTTValNONE);

			anXmlHandler->setAttributeValue(kTTSym_object, args);

			args = TTValue(TT(xmlConfigFilePath));
			anXmlHandler->sendMessage(TT("Read"), args, kTTValNONE);
		}
		else
			TTLogMessage("Modular -- \"%s\" application already exists", getLocalApplicationName->getCString());
	}
}

TTNodeAddressItemPtr	TTModularNamespacesLookup(TTSymbolPtr namespaceName)
{
	TTNodeAddressItemPtr	aNamespace = NULL;
	TTValue			v;

	if (namespaceName != kTTSymEmpty && namespaceName != kTTSym_none) {

		if (!TTModularNamespaces->lookup(namespaceName, v))
			v.get(0, (TTPtr*)&aNamespace);

		else {
			aNamespace = new TTNodeAddressItem();

			v = TTValue((TTPtr)aNamespace);
			TTModularNamespaces->append(namespaceName, v);
		}
	}

	return aNamespace;
}

#ifdef TT_PLATFORM_LINUX
int main(void)
{
	// TODO: should we call TTModularInit() here?
	return 0;
}
#endif<commit_msg>Commenting lines used to debug<commit_after>/*
 * TTModular Library
 * Copyright © 2010, Théo de la Hogue
 *
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTModular.h"

// Statics and Globals
static bool TTModularHasInitialized = false;

TTApplicationManagerPtr	TTModularApplications = NULL;

TTHashPtr TTModularNamespaces = NULL;

/****************************************************************************************************/

void TTModularInit()
{
	// Initialized Foundation framework
	TTFoundationInit();

	/* DEBUG
	TTObjectPtr test;
	TTValue v;
	TTObjectInstantiate(TT("nodelib.test"), &test, kTTValNONE);
	test->test(v); */

	if (!TTModularHasInitialized) {

		TTModularHasInitialized = true;

		// register classes -- both internal and external
		TTApplication::registerClass();
		TTApplicationManager::registerClass();
		TTContainer::registerClass();
		TTCue::registerClass();
		TTCueManager::registerClass();
		TTData::registerClass();
		TTExplorer::registerClass();
		TTInput::registerClass();
		TTMapper::registerClass();
		TTMapperManager::registerClass();
		TTMirror::registerClass();
		TTOpmlHandler::registerClass();
		TTOutput::registerClass();
		TTPreset::registerClass();
		TTPresetManager::registerClass();
		TTReceiver::registerClass();
		TTSender::registerClass();
		TTScript::registerClass();
		TTSubscriber::registerClass();
		TTTextHandler::registerClass();
		TTViewer::registerClass();
		TTXmlHandler::registerClass();

		TTModularSymbolCacheInit();
		//TTModularValueCacheInit();

		// to - this a very strange bug : the two first toString() parsing on number failed !?!
		// so here are two parsing to avoid this strange bug for instant ...
		TTString s;
		TTValue v;

		s = "0.001";
		v = s;
		v.fromString();

		v.clear();
		s = "1";
		v = s;
		v.fromString();

		// Create the Modular application manager with no application inside
		TTObjectInstantiate(kTTSym_ApplicationManager, TTObjectHandle(&TTModularApplications), kTTValNONE);

		// Create a hash table to manage namespace selections
		TTModularNamespaces = new TTHash();

#ifdef TT_DEBUG
		TTLogMessage("Modular -- Version %s -- Debugging Enabled\n", TTMODULAR_VERSION_STRING);
#else
		TTLogMessage("Modular -- Version %s\n", TTMODULAR_VERSION_STRING);
#endif

	}
}

void TTModularCreateLocalApplication(TTString applicationStr, TTString xmlConfigFilePath)
{
	TTValue				args;
	TTApplicationPtr	anApplication = NULL;

	if (TTModularApplications) {

		// if the local application doesn't exist yet
		if (!getLocalApplication) {

			// create the application
			args = TTValue(TT(applicationStr.data()));
			TTObjectInstantiate(kTTSym_Application, TTObjectHandle(&anApplication), args);

			// set it as local application
			args = TTValue((TTPtr)anApplication);
			TTModularApplications->setAttributeValue(TT("localApplication"), args);

			// Read xml configuration file
			TTXmlHandlerPtr anXmlHandler = NULL;
			TTObjectInstantiate(kTTSym_XmlHandler, TTObjectHandle(&anXmlHandler), kTTValNONE);

			anXmlHandler->setAttributeValue(kTTSym_object, args);

			args = TTValue(TT(xmlConfigFilePath));
			anXmlHandler->sendMessage(TT("Read"), args, kTTValNONE);
		}
		else
			TTLogMessage("Modular -- \"%s\" application already exists", getLocalApplicationName->getCString());
	}
}

TTNodeAddressItemPtr	TTModularNamespacesLookup(TTSymbolPtr namespaceName)
{
	TTNodeAddressItemPtr	aNamespace = NULL;
	TTValue			v;

	if (namespaceName != kTTSymEmpty && namespaceName != kTTSym_none) {

		if (!TTModularNamespaces->lookup(namespaceName, v))
			v.get(0, (TTPtr*)&aNamespace);

		else {
			aNamespace = new TTNodeAddressItem();

			v = TTValue((TTPtr)aNamespace);
			TTModularNamespaces->append(namespaceName, v);
		}
	}

	return aNamespace;
}

#ifdef TT_PLATFORM_LINUX
int main(void)
{
	// TODO: should we call TTModularInit() here?
	return 0;
}
#endif<|endoftext|>


<commit_before>/*
    Copyright (C) 1998 by Jorrit Tyberghein

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include "cssys/csshlib.h"
#ifdef __CYGWIN__
#include <sys/cygwin.h>
#endif
#include "csutil/csstrvec.h"
#include "csutil/util.h"
#include <windows.h>

static csStrVector ErrorMessages;

csLibraryHandle csFindLoadLibrary (const char *iName)
{
  ErrorMessages.DeleteAll();
  return csFindLoadLibrary (NULL, iName, ".dll");
}

csLibraryHandle csLoadLibrary (const char* iName)
{
  csLibraryHandle handle;
#ifdef __CYGWIN__
  // Cygwin wants to have Win32 paths not Unix paths.
  char *tmp=new char[1024];
  if (cygwin_conv_to_win32_path (iName,tmp))
  {
    ErrorMessages.Push(
	csStrNew("LoadLibrary() Cygwin/Win32 path conversion failed."));
    delete[] tmp;
    return 0;
  }
  handle = LoadLibrary (tmp);
  delete[] tmp;
#else
  handle = LoadLibrary (iName);
#endif
  if (handle == NULL)
  {
    char *buf;
    DWORD errorCode = GetLastError();
    FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &buf, 0, NULL);
    char *str = new char[strlen(buf) + strlen(iName) + 50];
    sprintf(str, "LoadLibrary('%s') error %d: %s",
	iName, (int)errorCode, buf);
    ErrorMessages.Push(str);
    LocalFree (buf);
  }
  return handle;
}

void* csGetLibrarySymbol(csLibraryHandle Handle, const char* Name)
{
  void *ptr = (void*)GetProcAddress ((HMODULE)Handle, Name);
  if (!ptr)
  {
    char *Name2;
    Name2 = new char [strlen (Name) + 2];
    strcpy (Name2, "_");
    strcat (Name2, Name);
    ptr = (void*)GetProcAddress ((HMODULE)Handle, Name2);
    delete [] Name2;
  }
  return ptr;
}

bool csUnloadLibrary (csLibraryHandle Handle)
{
  return FreeLibrary ((HMODULE)Handle)!=0;
}

void csPrintLibraryError (const char *iModule)
{
  char *str;
  fprintf(stderr, "ERROR (%s):\n", iModule);
  while((str = (char*)ErrorMessages.Pop()) != NULL)
  {
    fprintf (stderr, "    %s", str);
    delete[] str;
  }
}
<commit_msg>- reduced number of spaces in csPrintLibraryError() (caused linebreaks at   least for german 'file not found'... two should be enough for visual grouping   of the messages)<commit_after>/*
    Copyright (C) 1998 by Jorrit Tyberghein

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include "cssys/csshlib.h"
#ifdef __CYGWIN__
#include <sys/cygwin.h>
#endif
#include "csutil/csstrvec.h"
#include "csutil/util.h"
#include <windows.h>

static csStrVector ErrorMessages;

csLibraryHandle csFindLoadLibrary (const char *iName)
{
  ErrorMessages.DeleteAll();
  return csFindLoadLibrary (NULL, iName, ".dll");
}

csLibraryHandle csLoadLibrary (const char* iName)
{
  csLibraryHandle handle;
#ifdef __CYGWIN__
  // Cygwin wants to have Win32 paths not Unix paths.
  char *tmp=new char[1024];
  if (cygwin_conv_to_win32_path (iName,tmp))
  {
    ErrorMessages.Push(
	csStrNew("LoadLibrary() Cygwin/Win32 path conversion failed."));
    delete[] tmp;
    return 0;
  }
  handle = LoadLibrary (tmp);
  delete[] tmp;
#else
  handle = LoadLibrary (iName);
#endif
  if (handle == NULL)
  {
    char *buf;
    DWORD errorCode = GetLastError();
    FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &buf, 0, NULL);
    char *str = new char[strlen(buf) + strlen(iName) + 50];
    sprintf(str, "LoadLibrary('%s') error %d: %s",
	iName, (int)errorCode, buf);
    ErrorMessages.Push(str);
    LocalFree (buf);
  }
  return handle;
}

void* csGetLibrarySymbol(csLibraryHandle Handle, const char* Name)
{
  void *ptr = (void*)GetProcAddress ((HMODULE)Handle, Name);
  if (!ptr)
  {
    char *Name2;
    Name2 = new char [strlen (Name) + 2];
    strcpy (Name2, "_");
    strcat (Name2, Name);
    ptr = (void*)GetProcAddress ((HMODULE)Handle, Name2);
    delete [] Name2;
  }
  return ptr;
}

bool csUnloadLibrary (csLibraryHandle Handle)
{
  return FreeLibrary ((HMODULE)Handle)!=0;
}

void csPrintLibraryError (const char *iModule)
{
  char *str;
  fprintf(stderr, "ERROR (%s):\n", iModule);
  while((str = (char*)ErrorMessages.Pop()) != NULL)
  {
    fprintf (stderr, "  %s", str);
    delete[] str;
  }
}
<|endoftext|>


<commit_before><commit_msg>remove test for spurious duplicate keyspan device name on OS X.<commit_after><|endoftext|>


<commit_before>#include <string>
#include <sstream>
#include <tinyxml2.h>
#include <clocale>
#include <limits>
#include "utils.hpp"
#include "fluid/dlg_search.hpp"

void dlg_search::create_ex()
{
    m_markerid = std::numeric_limits<size_t>::max();

    // Set the window icon
    florb::utils::set_window_icon(m_window);

    try {
        m_downloader = new florb::downloader(1);
    } catch (std::runtime_error& e) {
        m_window->hide();
        throw e;
    }

    m_downloader->timeout(20);
    register_event_handler<dlg_search, florb::downloader::event_complete>(this, &dlg_search::evt_downloadcomplete_ex);
    m_downloader->add_event_listener(this);
}

void dlg_search::destroy_ex()
{
    if (m_downloader)
        delete m_downloader;

    if (m_window)
        delete m_window;
}

void dlg_search::cb_btn_search_ex(Fl_Widget *widget)
{
    std::string query(m_input_query->value());
    if (query.length() == 0)
        return;

    if (m_markerid != std::numeric_limits<size_t>::max())
    {
        m_wgtmap->marker_remove(m_markerid);
        m_markerid = std::numeric_limits<size_t>::max();
    }

    // Perform some very basic string sanitation
    size_t pos;
    while((pos = query.find("?")) != std::string::npos)
        query.replace(pos, 1, "");
    while((pos = query.find("/")) != std::string::npos)
        query.replace(pos, 1, "");
    while((pos = query.find("\\")) != std::string::npos)
        query.replace(pos, 1, "");
    while((pos = query.find("=")) != std::string::npos)
        query.replace(pos, 1, "");

    m_btn_search->deactivate();
    m_btn_ok->deactivate();
    m_input_query->deactivate();
    m_browser_results->deactivate();
    m_browser_results->clear();
    m_searchresults.clear();

    // Construct query string
    std::ostringstream oss;
    oss << "http://nominatim.openstreetmap.org/search/";
    oss << query;
    oss << "?format=xml";

    // Download the search results
    bool ret = m_downloader->queue(oss.str(), NULL);
    if (!ret)
    {
        m_btn_search->activate();
        m_btn_ok->activate();
        m_input_query->activate();
        m_browser_results->activate();
    }
}

void dlg_search::cb_browser_results_ex(Fl_Widget *widget)
{
    int v = m_browser_results->value();
    if (v == 0)
    {
        if (m_markerid != std::numeric_limits<size_t>::max())
        {
            m_wgtmap->marker_remove(m_markerid);
            m_markerid = std::numeric_limits<size_t>::max();
        }

        return;
    }

    if (m_markerid != std::numeric_limits<size_t>::max())
        m_wgtmap->marker_remove(m_markerid);

    m_markerid = m_wgtmap->marker_add(florb::utils::wsg842merc(m_searchresults[v-1].m_pos));
    m_wgtmap->goto_pos(m_searchresults[v-1].m_pos);
}

void dlg_search::cb_btn_ok_ex(Fl_Widget *widget)
{
    hide_ex();
}

void dlg_search::cb_window_ex(Fl_Widget *widget)
{
    hide_ex();
}

void dlg_search::show_ex()
{
    // Show the window
    m_window->show();
}

void dlg_search::hide_ex()
{
    if (m_markerid != std::numeric_limits<size_t>::max())
    {
        m_wgtmap->marker_remove(m_markerid);
        m_markerid = std::numeric_limits<size_t>::max();
    }

    // hide the window
    m_window->hide();
}

void dlg_search::process_download_ex()
{
    // TinyXML's number parsing is locale dependent, so we switch to "C"
    // and back after parsing
    char *poldlc;
    char oldlc[16];
    poldlc = setlocale(LC_ALL, NULL);
    strncpy(oldlc, poldlc, 15);
    oldlc[15] = '\0';
    setlocale(LC_ALL, "C");

    // Parse response
    for (;;)
    {
        florb::downloader::download dtmp;
        if (!m_downloader->get(dtmp))
            break;

        tinyxml2::XMLDocument doc;
        if (doc.Parse(std::string(dtmp.buf().begin(), dtmp.buf().end()).c_str()) != tinyxml2::XML_NO_ERROR)
            break;

        tinyxml2::XMLElement* root = doc.RootElement();
        if (!root)
            break;

        if (std::string(root->ToElement()->Value()).compare("searchresults") != 0)
            break;

        tinyxml2::XMLNode *child;
        for (child = root->FirstChild(); child != NULL; child = child->NextSibling())
        {
            if (std::string(child->ToElement()->Value()).compare("place") != 0)
                continue;

            const char *dn = child->ToElement()->Attribute("display_name");
            if (dn == NULL)
                continue;

            double lat = 1234.5, lon = 1234.5;
            child->ToElement()->QueryDoubleAttribute("lat", &lat);
            child->ToElement()->QueryDoubleAttribute("lon", &lon);

            // Check for error
            if ((lat == 1234.5) || (lon == 1234.5))
                continue;

            searchresult tmp;
            tmp.m_displayname = std::string(dn);
            tmp.m_pos = florb::point2d<double>(lon,lat);

            m_searchresults.push_back(tmp);
            m_browser_results->add(dn);
        }

        break;
    }

    // Switch back to original locale
    setlocale(LC_ALL, oldlc);

    m_btn_search->activate();
    m_btn_ok->activate();
    m_input_query->activate();
    m_browser_results->activate();
}

void dlg_search::cb_download_ex(void *userdata)
{
    // This might be a callback for an already destroyed layer instance
    dlg_search *d = static_cast<dlg_search*>(userdata);
    d->process_download_ex();
}

bool dlg_search::evt_downloadcomplete_ex(const florb::downloader::event_complete *e)
{
    Fl::awake(cb_download_ex, this);
    return true;
}

<commit_msg>Improve search dialog focus handling.<commit_after>#include <string>
#include <sstream>
#include <tinyxml2.h>
#include <clocale>
#include <limits>
#include "utils.hpp"
#include "fluid/dlg_search.hpp"

void dlg_search::create_ex()
{
    m_markerid = std::numeric_limits<size_t>::max();

    // Set the window icon
    florb::utils::set_window_icon(m_window);

    try {
        m_downloader = new florb::downloader(1);
    } catch (std::runtime_error& e) {
        m_window->hide();
        throw e;
    }

    m_downloader->timeout(20);
    register_event_handler<dlg_search, florb::downloader::event_complete>(this, &dlg_search::evt_downloadcomplete_ex);
    m_downloader->add_event_listener(this);
}

void dlg_search::destroy_ex()
{
    if (m_downloader)
        delete m_downloader;

    if (m_window)
        delete m_window;
}

void dlg_search::cb_btn_search_ex(Fl_Widget *widget)
{
    std::string query(m_input_query->value());
    if (query.length() == 0)
        return;

    if (m_markerid != std::numeric_limits<size_t>::max())
    {
        m_wgtmap->marker_remove(m_markerid);
        m_markerid = std::numeric_limits<size_t>::max();
    }

    // Perform some very basic string sanitation
    size_t pos;
    while((pos = query.find("?")) != std::string::npos)
        query.replace(pos, 1, "");
    while((pos = query.find("/")) != std::string::npos)
        query.replace(pos, 1, "");
    while((pos = query.find("\\")) != std::string::npos)
        query.replace(pos, 1, "");
    while((pos = query.find("=")) != std::string::npos)
        query.replace(pos, 1, "");

    m_btn_search->deactivate();
    m_btn_ok->deactivate();
    m_input_query->deactivate();
    m_browser_results->deactivate();
    m_browser_results->clear();
    m_searchresults.clear();

    // Construct query string
    std::ostringstream oss;
    oss << "http://nominatim.openstreetmap.org/search/";
    oss << query;
    oss << "?format=xml";

    // Download the search results
    bool ret = m_downloader->queue(oss.str(), NULL);
    if (!ret)
    {
        m_btn_search->activate();
        m_btn_ok->activate();
        m_input_query->activate();
        m_browser_results->activate();
    }
}

void dlg_search::cb_browser_results_ex(Fl_Widget *widget)
{
    int v = m_browser_results->value();
    if (v == 0)
    {
        if (m_markerid != std::numeric_limits<size_t>::max())
        {
            m_wgtmap->marker_remove(m_markerid);
            m_markerid = std::numeric_limits<size_t>::max();
        }

        return;
    }

    if (m_markerid != std::numeric_limits<size_t>::max())
        m_wgtmap->marker_remove(m_markerid);

    m_markerid = m_wgtmap->marker_add(florb::utils::wsg842merc(m_searchresults[v-1].m_pos));
    m_wgtmap->goto_pos(m_searchresults[v-1].m_pos);
}

void dlg_search::cb_btn_ok_ex(Fl_Widget *widget)
{
    hide_ex();
}

void dlg_search::cb_window_ex(Fl_Widget *widget)
{
    hide_ex();
}

void dlg_search::show_ex()
{
    // Focus on query input
    m_input_query->position(0, std::string(m_input_query->value()).length());
    m_input_query->take_focus();

    // Show the window
    m_window->show();
}

void dlg_search::hide_ex()
{
    if (m_markerid != std::numeric_limits<size_t>::max())
    {
        m_wgtmap->marker_remove(m_markerid);
        m_markerid = std::numeric_limits<size_t>::max();
    }

    // hide the window
    m_window->hide();
}

void dlg_search::process_download_ex()
{
    // TinyXML's number parsing is locale dependent, so we switch to "C"
    // and back after parsing
    char *poldlc;
    char oldlc[16];
    poldlc = setlocale(LC_ALL, NULL);
    strncpy(oldlc, poldlc, 15);
    oldlc[15] = '\0';
    setlocale(LC_ALL, "C");

    // Parse response
    for (;;)
    {
        florb::downloader::download dtmp;
        if (!m_downloader->get(dtmp))
            break;

        tinyxml2::XMLDocument doc;
        if (doc.Parse(std::string(dtmp.buf().begin(), dtmp.buf().end()).c_str()) != tinyxml2::XML_NO_ERROR)
            break;

        tinyxml2::XMLElement* root = doc.RootElement();
        if (!root)
            break;

        if (std::string(root->ToElement()->Value()).compare("searchresults") != 0)
            break;

        tinyxml2::XMLNode *child;
        for (child = root->FirstChild(); child != NULL; child = child->NextSibling())
        {
            if (std::string(child->ToElement()->Value()).compare("place") != 0)
                continue;

            const char *dn = child->ToElement()->Attribute("display_name");
            if (dn == NULL)
                continue;

            double lat = 1234.5, lon = 1234.5;
            child->ToElement()->QueryDoubleAttribute("lat", &lat);
            child->ToElement()->QueryDoubleAttribute("lon", &lon);

            // Check for error
            if ((lat == 1234.5) || (lon == 1234.5))
                continue;

            searchresult tmp;
            tmp.m_displayname = std::string(dn);
            tmp.m_pos = florb::point2d<double>(lon,lat);

            m_searchresults.push_back(tmp);
            m_browser_results->add(dn);
        }

        break;
    }

    // Switch back to original locale
    setlocale(LC_ALL, oldlc);

    m_btn_search->activate();
    m_btn_ok->activate();
    m_input_query->activate();
    m_browser_results->activate();
}

void dlg_search::cb_download_ex(void *userdata)
{
    // This might be a callback for an already destroyed layer instance
    dlg_search *d = static_cast<dlg_search*>(userdata);
    d->process_download_ex();
}

bool dlg_search::evt_downloadcomplete_ex(const florb::downloader::event_complete *e)
{
    Fl::awake(cb_download_ex, this);
    return true;
}

<|endoftext|>