Exemplo n.º 1
0
Arquivo: file.c Projeto: inilabs/caer
static bool caerOutputFileInit(caerModuleData moduleData) {
	// First, always create all needed setting nodes, set their default values
	// and add their listeners.
	char *userHomeDir = getUserHomeDirectory(moduleData);
	if (userHomeDir == NULL) {
		// caerModuleLog() called inside getUserHomeDirectory().
		return (false);
	}

	sshsNodeCreateString(moduleData->moduleNode, "directory", userHomeDir, 1, (PATH_MAX - MAX_PREFIX_LENGTH),
		SSHS_FLAGS_NORMAL, "Directory to write output data files in.");
	free(userHomeDir);

	// Support file-chooser in GUI, select any directory.
	sshsNodeCreateAttributeFileChooser(moduleData->moduleNode, "directory", "DIRECTORY");

	sshsNodeCreateString(moduleData->moduleNode, "prefix", DEFAULT_PREFIX, 1, MAX_PREFIX_LENGTH, SSHS_FLAGS_NORMAL,
		"Output data files name prefix.");

	// Generate current file name and open it.
	char *directory = sshsNodeGetString(moduleData->moduleNode, "directory");
	char *prefix    = sshsNodeGetString(moduleData->moduleNode, "prefix");

	char *filePath = getFullFilePath(moduleData, directory, prefix);
	free(directory);
	free(prefix);

	if (filePath == NULL) {
		// caerModuleLog() called inside getFullFilePath().
		return (false);
	}

	int fileFd = open(filePath, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR | S_IRGRP);
	if (fileFd < 0) {
		caerModuleLog(moduleData, CAER_LOG_CRITICAL,
			"Could not create or open output file '%s' for writing. Error: %d.", filePath, errno);
		free(filePath);

		return (false);
	}

	caerModuleLog(moduleData, CAER_LOG_INFO, "Opened output file '%s' successfully for writing.", filePath);
	free(filePath);

	if (!caerOutputCommonInit(moduleData, fileFd, NULL)) {
		close(fileFd);

		return (false);
	}

	return (true);
}
Exemplo n.º 2
0
static bool caerOutputUnixSocketServerInit(caerModuleData moduleData) {
	// First, always create all needed setting nodes, set their default values
	// and add their listeners.
	sshsNodeCreateString(moduleData->moduleNode, "socketPath", "/tmp/caer.sock", 2, PATH_MAX, SSHS_FLAGS_NORMAL,
		"Unix Socket path for writing output data (server mode, create new socket).");
	sshsNodeCreateInt(
		moduleData->moduleNode, "backlogSize", 5, 1, 32, SSHS_FLAGS_NORMAL, "Maximum number of pending connections.");
	sshsNodeCreateInt(moduleData->moduleNode, "concurrentConnections", 10, 1, 128, SSHS_FLAGS_NORMAL,
		"Maximum number of concurrent active connections.");

	// Allocate memory.
	size_t numClients         = (size_t) sshsNodeGetInt(moduleData->moduleNode, "concurrentConnections");
	outputCommonNetIO streams = malloc(sizeof(*streams) + (numClients * sizeof(uv_stream_t *)));
	if (streams == NULL) {
		caerModuleLog(moduleData, CAER_LOG_ERROR, "Failed to allocate memory for streams structure.");
		return (false);
	}

	streams->server = malloc(sizeof(uv_pipe_t));
	if (streams->server == NULL) {
		free(streams);

		caerModuleLog(moduleData, CAER_LOG_ERROR, "Failed to allocate memory for network server.");
		return (false);
	}

	// Initialize common info.
	streams->isTCP         = false;
	streams->isUDP         = false;
	streams->isPipe        = true;
	streams->activeClients = 0;
	streams->clientsSize   = numClients;
	for (size_t i = 0; i < streams->clientsSize; i++) {
		streams->clients[i] = NULL;
	}

	// Remember address.
	streams->address = sshsNodeGetString(moduleData->moduleNode, "socketPath");

	streams->server->data = streams;

	// Initialize loop and network handles.
	int retVal = uv_loop_init(&streams->loop);
	UV_RET_CHECK(retVal, moduleData->moduleSubSystemString, "uv_loop_init", free(streams->server);
				 free(streams->address); free(streams); return (false));

	retVal = uv_pipe_init(&streams->loop, (uv_pipe_t *) streams->server, false);
	UV_RET_CHECK(retVal, moduleData->moduleSubSystemString, "uv_pipe_init", uv_loop_close(&streams->loop);
				 free(streams->server); free(streams->address); free(streams); return (false));

	retVal = uv_pipe_bind((uv_pipe_t *) streams->server, streams->address);
	UV_RET_CHECK(retVal, moduleData->moduleSubSystemString, "uv_pipe_bind", libuvCloseLoopHandles(&streams->loop);
				 uv_loop_close(&streams->loop); free(streams->address); free(streams); return (false));

	retVal = uv_listen(
		streams->server, sshsNodeGetInt(moduleData->moduleNode, "backlogSize"), &caerOutputCommonOnServerConnection);
	UV_RET_CHECK(retVal, moduleData->moduleSubSystemString, "uv_listen", libuvCloseLoopHandles(&streams->loop);
				 uv_loop_close(&streams->loop); free(streams->address); free(streams); return (false));

	// Start.
	if (!caerOutputCommonInit(moduleData, -1, streams)) {
		libuvCloseLoopHandles(&streams->loop);
		uv_loop_close(&streams->loop);
		free(streams->address);
		free(streams);

		return (false);
	}

	return (true);
}
Exemplo n.º 3
0
static bool caerOutputUnixSocketServerInit(caerModuleData moduleData) {
	// First, always create all needed setting nodes, set their default values
	// and add their listeners.
	sshsNodePutStringIfAbsent(moduleData->moduleNode, "socketPath", "/tmp/caer.sock");
	sshsNodePutShortIfAbsent(moduleData->moduleNode, "backlogSize", 5);
	sshsNodePutShortIfAbsent(moduleData->moduleNode, "concurrentConnections", 10);

	// Open a Unix local socket on a known path, to be accessed by other processes (server-like mode).
	int serverSockFd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (serverSockFd < 0) {
		caerLog(CAER_LOG_CRITICAL, moduleData->moduleSubSystemString, "Could not create local Unix socket. Error: %d.",
		errno);
		return (false);
	}

	struct sockaddr_un unixSocketAddr;
	memset(&unixSocketAddr, 0, sizeof(struct sockaddr_un));

	unixSocketAddr.sun_family = AF_UNIX;

	char *socketPath = sshsNodeGetString(moduleData->moduleNode, "socketPath");
	strncpy(unixSocketAddr.sun_path, socketPath, sizeof(unixSocketAddr.sun_path) - 1);
	unixSocketAddr.sun_path[sizeof(unixSocketAddr.sun_path) - 1] = '\0'; // Ensure NUL terminated string.
	free(socketPath);

	// Bind socket to above address.
	if (bind(serverSockFd, (struct sockaddr *) &unixSocketAddr, sizeof(struct sockaddr_un)) < 0) {
		close(serverSockFd);

		caerLog(CAER_LOG_CRITICAL, moduleData->moduleSubSystemString, "Could not bind local Unix socket. Error: %d.",
		errno);
		return (false);
	}

	// Listen to new connections on the socket.
	if (listen(serverSockFd, sshsNodeGetShort(moduleData->moduleNode, "backlogSize")) < 0) {
		close(serverSockFd);

		caerLog(CAER_LOG_CRITICAL, moduleData->moduleSubSystemString,
			"Could not listen on local Unix socket. Error: %d.", errno);
		return (false);
	}

	outputCommonFDs fileDescriptors = caerOutputCommonAllocateFdArray(
		(size_t) sshsNodeGetShort(moduleData->moduleNode, "concurrentConnections"));
	if (fileDescriptors == NULL) {
		close(serverSockFd);

		caerLog(CAER_LOG_CRITICAL, moduleData->moduleSubSystemString,
			"Unable to allocate memory for file descriptors.");
		return (false);
	}

	fileDescriptors->serverFd = serverSockFd;

	if (!caerOutputCommonInit(moduleData, fileDescriptors, true, false)) {
		close(serverSockFd);
		free(fileDescriptors);

		return (false);
	}

	caerLog(CAER_LOG_INFO, moduleData->moduleSubSystemString, "Local Unix socket ready at '%s'.",
		unixSocketAddr.sun_path);

	return (true);
}