Esempio n. 1
0
string
strip(const StaticString &str) {
	const char *data = str.data();
	const char *end = str.data() + str.size();
	while (data < end && (*data == ' ' || *data == '\n' || *data == '\t')) {
		data++;
	}
	while (end > data && (end[-1] == ' ' || end[-1] == '\n' || end[-1] == '\t')) {
		end--;
	}
	return string(data, end - data);
}
Esempio n. 2
0
void
setupNonBlockingTcpSocket(NTCP_State &state, const StaticString &hostname, int port) {
	int ret;

	memset(&state.hints, 0, sizeof(state.hints));
	state.hints.ai_family   = PF_UNSPEC;
	state.hints.ai_socktype = SOCK_STREAM;
	ret = getaddrinfo(hostname.toString().c_str(), toString(port).c_str(),
		&state.hints, &state.res);
	if (ret != 0) {
		string message = "Cannot resolve IP address '";
		message.append(hostname.data(), hostname.size());
		message.append(":");
		message.append(toString(port));
		message.append("': ");
		message.append(gai_strerror(ret));
		throw IOException(message);
	}

	state.fd = syscalls::socket(PF_INET, SOCK_STREAM, 0);
	if (state.fd == -1) {
		int e = errno;
		throw SystemException("Cannot create a TCP socket file descriptor", e);
	}

	state.hostname = hostname;
	state.port = port;
	setNonBlocking(state.fd);
}
Esempio n. 3
0
static Numeric
hexToUnsignedNumeric(const StaticString &hex) {
	const char *pos = hex.data();
	const char *end = hex.data() + hex.size();
	Numeric result = 0;
	bool done = false;
	
	while (pos < end && !done) {
		char c = *pos;
		if (c >= '0' && c <= '9') {
			result *= 16;
			result += c - '0';
		} else if (c >= 'a' && c <= 'f') {
			result *= 16;
			result += 10 + (c - 'a');
		} else if (c >= 'A' && c <= 'F') {
			result *= 16;
			result += 10 + (c - 'A');
		} else {
			done = true;
		}
		pos++;
	}
	return result;
}
Esempio n. 4
0
static Numeric
stringToSignedNumeric(const StaticString &str) {
	Numeric result = 0;
	string::size_type i = 0;
	const char *data = str.data();
	bool minus = false;
	
	while (data[i] == ' ' && i < str.size()) {
		i++;
	}
	if (data[i] == '-') {
		minus = true;
		i++;
	}
	while (data[i] >= '0' && data[i] <= '9' && i < str.size()) {
		result *= 10;
		result += data[i] - '0';
		i++;
	}
	if (minus) {
		return -result;
	} else {
		return result;
	}
}
Esempio n. 5
0
int
connectToUnixServer(const StaticString &filename, const char *file,
	unsigned int line)
{
	int fd = syscalls::socket(PF_UNIX, SOCK_STREAM, 0);
	if (fd == -1) {
		int e = errno;
		throw SystemException("Cannot create a Unix socket file descriptor", e);
	}

	FdGuard guard(fd, file, line, true);
	int ret;
	struct sockaddr_un addr;

	if (filename.size() > sizeof(addr.sun_path) - 1) {
		string message = "Cannot connect to Unix socket '";
		message.append(filename.data(), filename.size());
		message.append("': filename is too long.");
		throw RuntimeException(message);
	}

	addr.sun_family = AF_UNIX;
	memcpy(addr.sun_path, filename.c_str(), filename.size());
	addr.sun_path[filename.size()] = '\0';

	bool retry = true;
	int counter = 0;
	while (retry) {
		ret = syscalls::connect(fd, (const sockaddr *) &addr, sizeof(addr));
		if (ret == -1) {
			#if defined(sun) || defined(__sun)
				/* Solaris has this nice kernel bug where connecting to
				 * a newly created Unix socket which is obviously
				 * connectable can cause an ECONNREFUSED. So we retry
				 * in a loop.
				 */
				retry = errno == ECONNREFUSED;
			#else
				retry = false;
			#endif
			retry = retry && counter < 9;

			if (retry) {
				syscalls::usleep((useconds_t) (10000 * pow((double) 2, (double) counter)));
				counter++;
			} else {
				int e = errno;
				string message("Cannot connect to Unix socket '");
				message.append(filename.toString());
				message.append("'");
				throw SystemException(message, e);
			}
		} else {
			guard.clear();
			return fd;
		}
	}
	abort();   // Never reached.
	return -1; // Shut up compiler warning.
}
Esempio n. 6
0
string
lookupSystemGroupnameByGid(gid_t gid, const StaticString &fallbackFormat) {
	OsGroup group;
	bool result;

	try {
		result = lookupSystemGroupByGid(gid, group);
	} catch (const SystemException &) {
		result = false;
	}

	if (result && group.grp.gr_name != NULL && group.grp.gr_name[0] != '\0') {
		return group.grp.gr_name;
	} else {
		// Null terminate fallback format string
		DynamicBuffer fallbackFormatNt(fallbackFormat.size() + 1);
		memcpy(fallbackFormatNt.data, fallbackFormat.data(), fallbackFormat.size());
		fallbackFormatNt.data[fallbackFormat.size()] = '\0';

		char buf[512];
		snprintf(buf, sizeof(buf), fallbackFormatNt.data, (int) gid);
		buf[sizeof(buf) - 1] = '\0';
		return buf;
	}
}
Esempio n. 7
0
string
lookupSystemUsernameByUid(uid_t uid, const StaticString &fallbackFormat) {
	OsUser user;
	bool result;

	try {
		result = lookupSystemUserByUid(uid, user);
	} catch (const SystemException &) {
		result = false;
	}

	if (result && user.pwd.pw_name != NULL && user.pwd.pw_name[0] != '\0') {
		return user.pwd.pw_name;
	} else {
		// Null terminate fallback format string
		DynamicBuffer fallbackFormatNt(fallbackFormat.size() + 1);
		memcpy(fallbackFormatNt.data, fallbackFormat.data(), fallbackFormat.size());
		fallbackFormatNt.data[fallbackFormat.size()] = '\0';

		char buf[512];
		snprintf(buf, sizeof(buf), fallbackFormatNt.data, (int) uid);
		buf[sizeof(buf) - 1] = '\0';
		return buf;
	}
}
Esempio n. 8
0
bool
constantTimeCompare(const StaticString &a, const StaticString &b) {
	// http://blog.jasonmooberry.com/2010/10/constant-time-string-comparison/
	// See also ActiveSupport::MessageVerifier#secure_compare.
	if (a.size() != b.size()) {
		return false;
	} else {
		const char *x = a.data();
		const char *y = b.data();
		const char *end = a.data() + a.size();
		int result = 0;

		while (x < end) {
			result |= *x ^ *y;
			x++;
			y++;
		}

		return result == 0;
	}
}
Esempio n. 9
0
/* {{{ Special objects that implement MongoDB\BSON\Serializable */
void VariantToBsonConverter::_convertSerializable(bson_t *bson, const char *key, Object v)
{
	Variant result;
	Array   properties;
	TypedValue args[1] = { *(Variant(v)).asCell() };
	Class *cls;
	Func *m;

	cls = v.get()->getVMClass();
	m = cls->lookupMethod(s_MongoDriverBsonSerializable_functionName.get());
	
	g_context->invokeFuncFew(
		result.asTypedValue(),
		m,
		v.get(),
		nullptr,
		1, args
	);

	if ( ! (
			result.isArray() || 
			(result.isObject() && result.toObject().instanceof(s_stdClass))
		)
	) {
		StringBuffer buf;
		buf.printf(
			"Expected %s::%s() to return an array or stdClass, %s given",
			cls->nameStr().c_str(),
			s_MongoDriverBsonSerializable_functionName.data(),
			result.isObject() ? result.toObject()->getVMClass()->nameStr().c_str() : HPHP::getDataTypeString(result.getType()).data()
		);
		Variant full_name = buf.detach();

		throw MongoDriver::Utils::throwUnexpectedValueException((char*) full_name.toString().c_str());
	}

	/* Convert to array so that we can handle it well */
	properties = result.toArray();

	if (v.instanceof(s_MongoDriverBsonPersistable_className)) {
		const char *class_name = cls->nameStr().c_str();
		Object obj = createMongoBsonBinaryObject(
			(const uint8_t *) class_name,
			strlen(class_name),
			(bson_subtype_t) 0x80
		);
		properties.add(String(s_MongoDriverBsonODM_fieldName), obj);
	}

	convertDocument(bson, key, result.isObject() ? Variant(Variant(properties).toObject()) : Variant(properties));
}
Esempio n. 10
0
/**
 * Linux-only way to change OOM killer configuration for
 * current process. Requires root privileges, which we
 * should have.
 */
static void
setOomScore(const StaticString &score) {
	if (score.empty()) {
		return;
	}

	FILE *f;
	OomFileType type;
	
	f = openOomAdjFile("w", type);
	if (f != NULL) {
		fwrite(score.data(), 1, score.size(), f);
		fclose(f);
	}
}
Esempio n. 11
0
static Numeric
stringToUnsignedNumeric(const StaticString &str) {
	Numeric result = 0;
	string::size_type i = 0;
	const char *data = str.data();
	
	while (data[i] == ' ' && i < str.size()) {
		i++;
	}
	while (data[i] >= '0' && data[i] <= '9' && i < str.size()) {
		result *= 10;
		result += data[i] - '0';
		i++;
	}
	return result;
}
Esempio n. 12
0
void
parseTcpSocketAddress(const StaticString &address, string &host, unsigned short &port) {
	if (getSocketAddressType(address) != SAT_TCP) {
		throw ArgumentException("Not a valid TCP socket address");
	}

	StaticString hostAndPort(address.data() + sizeof("tcp://") - 1,
		address.size() - sizeof("tcp://") + 1);
	if (hostAndPort.empty()) {
		throw ArgumentException("Not a valid TCP socket address");
	}

	if (hostAndPort[0] == '[') {
		// IPv6 address, e.g.:
		// [::1]:3000
		const char *hostEnd = (const char *) memchr(hostAndPort.data(), ']',
			hostAndPort.size());
		if (hostEnd == NULL || hostAndPort.size() <= string::size_type(hostEnd - hostAndPort.data()) + 3) {
			throw ArgumentException("Not a valid TCP socket address");
		}

		const char *sep = hostEnd + 1;
		host.assign(hostAndPort.data() + 1, hostEnd - hostAndPort.data() - 1);
		port = stringToUint(StaticString(
			sep + 1,
			hostAndPort.data() + hostAndPort.size() - sep - 1
		));

	} else {
		// IPv4 address, e.g.:
		// 127.0.0.1:3000
		const char *sep = (const char *) memchr(hostAndPort.data(), ':', hostAndPort.size());
		if (sep == NULL || hostAndPort.size() <= string::size_type(sep - hostAndPort.data()) + 2) {
			throw ArgumentException("Not a valid TCP socket address");
		}

		host.assign(hostAndPort.data(), sep - hostAndPort.data());
		port = stringToUint(StaticString(
			sep + 1,
			hostAndPort.data() + hostAndPort.size() - sep - 1
		));
	}
}
Esempio n. 13
0
bool
lookupSystemGroupByName(const StaticString &name, OsGroup &result) {
	TRACE_POINT();

	// Null terminate name
	DynamicBuffer ntName(name.size() + 1);
	memcpy(ntName.data, name.data(), name.size());
	ntName.data[name.size()] = '\0';

	int code;
	struct group *output = NULL;

	do {
		code = getgrnam_r(ntName.data, &result.grp, result.buffer.data,
			result.buffer.size, &output);
	} while (code == EINTR || code == EAGAIN);
	if (code == 0) {
		return output != NULL;
	} else {
		throw SystemException("Error looking up OS group account " + name, code);
	}
}
Esempio n. 14
0
void
writeExact(int fd, const StaticString &data, unsigned long long *timeout) {
	const char * restrict data_ptr = data.data();
	writeExact(fd, data_ptr, data.size(), timeout);
}