예제 #1
0
APIE process_set_identity(uid_t uid, gid_t gid) {
	APIE error_code;
	struct passwd *pw;
	gid_t groups[128]; // FIXME: maybe allocate this dynamically
	int length = sizeof(groups) / sizeof(gid_t);

	// get username
	pw = getpwuid(uid);

	if (pw == NULL) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not get passwd entry for user ID %u: %s (%d)",
		          uid, get_errno_name(errno), errno);

		return error_code;
	}

	// get (secondary) groups
	if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &length) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not get secondary groups for user ID %u: %s (%d)",
		          uid, get_errno_name(errno), errno);

		return error_code;
	}

	// set (primary) group
	if (setregid(gid, gid) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not change real and effective group ID to %u: %s (%d)",
		          gid, get_errno_name(errno), errno);

		return error_code;
	}

	// set (secondary) groups
	if (setgroups(length, groups) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not set secondary group IDs of user ID %u: %s (%d)",
		          uid, get_errno_name(errno), errno);

		return error_code;
	}

	// set user
	if (setreuid(uid, uid) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not change real and effective user ID to %u: %s (%d)",
		          uid, get_errno_name(errno), errno);

		return error_code;
	}

	return API_E_SUCCESS;
}
예제 #2
0
파일: main_windows.c 프로젝트: wopl/fhem
static void handle_device_event(DWORD event_type) {
	uint8_t byte = 0;

	switch (event_type) {
	case DBT_DEVICEARRIVAL:
		log_debug("Received device notification (type: arrival)");

		if (pipe_write(_notification_pipe[1], &byte, sizeof(byte)) < 0) {
			log_error("Could not write to notification pipe: %s (%d)",
			          get_errno_name(errno), errno);
		}

		break;

	case DBT_DEVICEREMOVECOMPLETE:
		log_debug("Received device notification (type: removal)");

		if (pipe_write(_notification_pipe[1], &byte, sizeof(byte)) < 0) {
			log_error("Could not write to notification pipe: %s (%d)",
			          get_errno_name(errno), errno);
		}

		break;
	}
}
예제 #3
0
파일: service.c 프로젝트: vszurma/brickd
int service_is_running(void) {
	SC_HANDLE service_control_manager;
	int rc;
	SC_HANDLE service;
	SERVICE_STATUS service_status;

	// open service control manager
	service_control_manager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);

	if (service_control_manager == NULL) {
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		log_error("Could not open service control manager: %s (%d)",
		          get_errno_name(rc), rc);

		return -1;
	}

	// open service
	service = OpenService(service_control_manager, _service_name,
	                      SERVICE_QUERY_STATUS);

	if (service == NULL) {
		rc = GetLastError();

		if (rc == ERROR_SERVICE_DOES_NOT_EXIST) {
			CloseServiceHandle(service_control_manager);

			return 0;
		}

		rc += ERRNO_WINAPI_OFFSET;

		log_error("Could not open '%s' service: %s (%d)",
		          _service_name, get_errno_name(rc), rc);

		CloseServiceHandle(service_control_manager);

		return -1;
	}

	// get service status
	if (!QueryServiceStatus(service, &service_status)) {
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		log_error("Could not query status of '%s' service: %s (%d)",
		          _service_name, get_errno_name(rc), rc);

		CloseServiceHandle(service);
		CloseServiceHandle(service_control_manager);

		return -1;
	}

	CloseServiceHandle(service);
	CloseServiceHandle(service_control_manager);

	return service_status.dwCurrentState != SERVICE_STOPPED ? 1 : 0;
}
예제 #4
0
// TODO: If we want "real parallel accessibility" of the EEPROM we need to
//       lock a mutex in the init function and unlock it in the release function
int i2c_eeprom_create(I2CEEPROM *i2c_eeprom, int extension) {
	GPIOREDPin pullup = {GPIO_RED_PORT_B, GPIO_RED_PIN_6};

	log_debug("Initializing I2C EEPROM for extension %d", extension);

	if (i2c_eeprom == NULL || extension < 0 || extension > 1) {
		log_error("Initialization of I2C EEPROM for extension %d failed (malformed parameters)",
		          extension);

		return -1;
	}

	// Enable pullups
	gpio_red_mux_configure(pullup, GPIO_RED_MUX_OUTPUT);
	gpio_red_output_clear(pullup);

	// Initialize I2C EEPROM structure
	i2c_eeprom->extension = extension;

	switch (extension) {
	case 0:
		i2c_eeprom->address_pin.port_index = GPIO_RED_PORT_G;
		i2c_eeprom->address_pin.pin_index = GPIO_RED_PIN_9;

		break;

	case 1:
		i2c_eeprom->address_pin.port_index = GPIO_RED_PORT_G;
		i2c_eeprom->address_pin.pin_index = GPIO_RED_PIN_13;

		break;
	}

	// enable I2C bus with GPIO_RED
	gpio_red_mux_configure(i2c_eeprom->address_pin, GPIO_RED_MUX_OUTPUT);
	i2c_eeprom_deselect(i2c_eeprom);

	i2c_eeprom->file = open(I2C_EEPROM_BUS, O_RDWR);

	if (i2c_eeprom->file < 0) {
		log_error("Initialization of I2C EEPROM for extension %d failed (Unable to open I2C bus: %s (%d))",
		          extension, get_errno_name(errno), errno);

		return -1;
	}

	if (ioctl(i2c_eeprom->file, I2C_SLAVE, I2C_EEPROM_DEVICE_ADDRESS) < 0) {
		log_error("Initialization of I2C EEPROM for extension %d failed (Unable to access I2C device on the bus: %s (%d))",
		          extension, get_errno_name(errno), errno);

		i2c_eeprom_destroy(i2c_eeprom);

		return -1;
	}

	return 0;
}
예제 #5
0
static void network_handle_accept(void *opaque) {
	Socket *server_socket = opaque;
	Socket *client_socket;
	struct sockaddr_storage address;
	socklen_t length = sizeof(address);
	char hostname[NI_MAXHOST];
	char port[NI_MAXSERV];
	char buffer[NI_MAXHOST + NI_MAXSERV + 4]; // 4 == strlen("[]:") + 1
	char *name = "<unknown>";
	Client *client;

	// accept new client socket
	client_socket = socket_accept(server_socket, (struct sockaddr *)&address, &length);

	if (client_socket == NULL) {
		if (!errno_interrupted()) {
			log_error("Could not accept new client socket: %s (%d)",
			          get_errno_name(errno), errno);
		}

		return;
	}

	if (socket_address_to_hostname((struct sockaddr *)&address, length,
	                               hostname, sizeof(hostname),
	                               port, sizeof(port)) < 0) {
		log_warn("Could not get hostname and port of client (socket: %d): %s (%d)",
		         client_socket->base.handle, get_errno_name(errno), errno);
	} else {
		if (address.ss_family == AF_INET6) {
			snprintf(buffer, sizeof(buffer), "[%s]:%s", hostname, port);
		} else {
			snprintf(buffer, sizeof(buffer), "%s:%s", hostname, port);
		}

		name = buffer;
	}

	// create new client
	client = network_create_client(name, &client_socket->base);

	if (client == NULL) {
		socket_destroy(client_socket);
		free(client_socket);

		return;
	}

#ifdef BRICKD_WITH_RED_BRICK
	client_send_red_brick_enumerate(client, ENUMERATION_TYPE_CONNECTED);
#endif
}
예제 #6
0
파일: mesh.c 프로젝트: Tinkerforge/brickd
void mesh_handle_accept(void *opaque) {
    char port[NI_MAXSERV];
    char *name = "<unknown>";
    char hostname[NI_MAXHOST];
    Socket *mesh_client_socket;
    // Socket that is created to the root node of a mesh network.
    struct sockaddr_storage address;
    socklen_t length = sizeof(address);
    Socket *mesh_listen_socket = opaque;
    char buffer[NI_MAXHOST + NI_MAXSERV + 4];

    log_info("New connection on mesh port");

    // Accept new mesh client socket.
    mesh_client_socket = socket_accept(mesh_listen_socket,
                                       (struct sockaddr *)&address,
                                       &length);

    if (mesh_client_socket == NULL) {
        if (!errno_interrupted()) {
            log_error("Failed to accept new mesh client connection: %s (%d)",
                      get_errno_name(errno), errno);
        }

        return;
    }

    if (socket_address_to_hostname((struct sockaddr *)&address, length,
                                   hostname, sizeof(hostname),
                                   port, sizeof(port)) < 0) {
        log_warn("Could not get hostname and port of mesh client (socket: %d): %s (%d)",
                 mesh_client_socket->base.handle, get_errno_name(errno), errno);
    }
    else {
        snprintf(buffer, sizeof(buffer), "%s:%s", hostname, port);

        name = buffer;
    }

    /*
     * Allocate and initialise a new mesh stack. Note that in this stage the stack
     * is not added to brickd's central list of stacks yet.
     */
    if (mesh_stack_create(name, &mesh_client_socket->base) < 0) {
        log_error("Could not create new mesh stack");
    }
    else {
        log_info("New mesh stack created");
    }
}
예제 #7
0
// public API
APIE process_kill(Process *process, ProcessSignal signal) {
	int rc;
	APIE error_code;

	// FIXME: here is a race condition, because the child process might already
	//        be dead at this point, but the process state didn't get updated
	//        yet. this can result in trying to kill a process that's not
	//        existing anymore. or even worse, the process ID has already been
	//        reused and an unrelated process gets killed here
	if (!process_is_alive(process)) {
		log_warn("Cannot send signal (number: %d) to an already dead child process (executable: %s)",
		         signal, process->executable->buffer);

		return API_E_INVALID_OPERATION;
	}

	rc = kill(process->pid, signal);

	if (rc < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not send signal (number: %d) to child process (executable: %s, pid: %u): %s (%d)",
		          signal, process->executable->buffer, process->pid, get_errno_name(errno), errno);

		return error_code;
	}

	return API_E_SUCCESS;
}
예제 #8
0
APIE inventory_add_object(Object *object) {
	Object **object_ptr;
	APIE error_code;

	error_code = inventory_get_next_object_id(&object->id);

	if (error_code != API_E_SUCCESS) {
		log_warn("Cannot add new %s object, all object IDs are in use",
		         object_get_type_name(object->type));

		return error_code;
	}

	object_ptr = array_append(&_objects[object->type]);

	if (object_ptr == NULL) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not append to %s object array: %s (%d)",
		          object_get_type_name(object->type),
		          get_errno_name(errno), errno);

		return error_code;
	}

	*object_ptr = object;

	log_object_debug("Added %s object (id: %u)",
	                 object_get_type_name(object->type), object->id);

	return API_E_SUCCESS;
}
예제 #9
0
APIE inventory_add_session(Session *session) {
	Session **session_ptr;
	APIE error_code;

	error_code = inventory_get_next_session_id(&session->id);

	if (error_code != API_E_SUCCESS) {
		log_warn("Cannot add new session, all session IDs are in use");

		return error_code;
	}

	session_ptr = array_append(&_sessions);

	if (session_ptr == NULL) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not append to session array: %s (%d)",
		          get_errno_name(errno), errno);

		return error_code;
	}

	*session_ptr = session;

	log_object_debug("Added session (id: %u)", session->id);

	return API_E_SUCCESS;
}
예제 #10
0
파일: mesh.c 프로젝트: Tinkerforge/brickd
int mesh_init(void) {
    uint16_t mesh_listen_port = \
                                (uint16_t)config_get_option_value("listen.mesh_port")->integer;

    if (mesh_listen_port == 0) {
        log_info("Mesh support is disabled");

        return 0;
    }

    log_info("Initializing mesh subsystem");

    if (mesh_start_listening(&mesh_listen_socket,
                             mesh_listen_port,
                             socket_create_allocated) >= 0) {
        is_mesh_listen_socket_open = true;
    }

    if (!is_mesh_listen_socket_open) {
        log_error("Could not open mesh listen socket");

        return -1;
    }

    // Create mesh stack array.
    if (array_create(&mesh_stacks, MAX_MESH_STACKS, sizeof(MeshStack), false) < 0) {
        log_error("Could not create mesh stack array: %s (%d)",
                  get_errno_name(errno), errno);

        return -1;
    }

    return 0;
}
예제 #11
0
static void handle_sighup(void) {
	FILE *log_file = log_get_file();

	if (log_file != NULL) {
		if (fileno(log_file) == STDOUT_FILENO || fileno(log_file) == STDERR_FILENO) {
			return; // don't close stdout or stderr
		}

		fclose(log_file);
	}

	log_file = fopen(_log_filename, "a+");

	if (log_file == NULL) {
		log_set_file(stderr);

		log_error("Could not reopen log file '%s': %s (%d)",
		          _log_filename, get_errno_name(errno), errno);

		return;
	}

	log_set_file(log_file);

	log_info("Reopened log file '%s'", _log_filename);
}
예제 #12
0
Client *network_create_client(const char *name, IO *io) {
	Client *client;

	// append to client array
	client = array_append(&_clients);

	if (client == NULL) {
		log_error("Could not append to client array: %s (%d)",
		          get_errno_name(errno), errno);

		return NULL;
	}

	// create new client that takes ownership of the I/O object
	if (client_create(client, name, io, _next_authentication_nonce++, NULL) < 0) {
		array_remove(&_clients, _clients.count - 1, NULL);

		return NULL;
	}

	log_info("Added new client ("CLIENT_SIGNATURE_FORMAT")",
	         client_expand_signature(client));

	return client;
}
예제 #13
0
파일: service.c 프로젝트: bjoern-r/brickd
int service_init(LPHANDLER_FUNCTION_EX handler) {
	int rc;

	_service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
	_service_status.dwCurrentState = SERVICE_STOPPED;
	_service_status.dwControlsAccepted = 0;
	_service_status.dwWin32ExitCode = NO_ERROR;
	_service_status.dwServiceSpecificExitCode = NO_ERROR;
	_service_status.dwCheckPoint = 0;
	_service_status.dwWaitHint = 0;

	_service_status_handle = RegisterServiceCtrlHandlerEx(_service_name,
	                                                      handler, NULL);

	if (_service_status_handle == 0) {
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		log_error("Could not register service control handler: %s (%d)",
		          get_errno_name(rc), rc);

		return -1;
	}

	return 0;
}
예제 #14
0
static int i2c_eeprom_set_pointer(I2CEEPROM *i2c_eeprom,
                                  uint8_t *eeprom_memory_address) {
	int bytes_written = 0;

	if (i2c_eeprom == NULL || i2c_eeprom->file < 0) {
		log_error("I2C EEPROM structure uninitialized");

		return -1;
	}

	bytes_written = robust_write(i2c_eeprom->file, eeprom_memory_address, 2);

	if (bytes_written != 2) {
		// We only use debug here to not spam the log with errors.
		// This is the expected case if an extension is not present.
		log_debug("Error setting EEPROM address pointer: %s (%d)",
		          get_errno_name(errno), errno);

		i2c_eeprom_destroy(i2c_eeprom);

		return -1;
	}

	return bytes_written;
}
예제 #15
0
파일: main_windows.c 프로젝트: wopl/fhem
static int service_run(int log_to_file, int debug) {
	SERVICE_TABLE_ENTRY service_table[2];
	int rc;

	service_table[0].lpServiceName = service_get_name();
	service_table[0].lpServiceProc = service_main;

	service_table[1].lpServiceName = NULL;
	service_table[1].lpServiceProc = NULL;

	if (!StartServiceCtrlDispatcher(service_table)) {
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		if (rc == ERRNO_WINAPI_OFFSET + ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) {
			log_info("Could not start as service, starting as console application");

			_run_as_service = 0;
			_pause_before_exit = started_by_explorer();

			return generic_main(log_to_file, debug);
		} else {
			log_error("Could not start service control dispatcher: %s (%d)",
			          get_errno_name(rc), rc);

			log_exit();

			config_exit();

			return EXIT_FAILURE;
		}
	}

	return EXIT_SUCCESS;
}
예제 #16
0
파일: main_windows.c 프로젝트: wopl/fhem
static LRESULT CALLBACK message_pump_window_proc(HWND hwnd, UINT msg,
                                                 WPARAM wparam, LPARAM lparam) {
	int rc;

	switch (msg) {
	case WM_USER:
		log_debug("Destroying message pump window");

		if (!DestroyWindow(hwnd)) {
			rc = ERRNO_WINAPI_OFFSET + GetLastError();

			log_warn("Could not destroy message pump window: %s (%d)",
			         get_errno_name(rc), rc);
		}

		return 0;

	case WM_DESTROY:
		log_debug("Posting quit message message loop");

		PostQuitMessage(0);

		return 0;

	case WM_DEVICECHANGE:
		handle_device_event(wparam);

		return TRUE;
	}

	return DefWindowProc(hwnd, msg, wparam, lparam);
}
예제 #17
0
파일: main_windows.c 프로젝트: wopl/fhem
static int get_process_image_name(PROCESSENTRY32 entry, char *buffer, DWORD length) {
	int rc;
	HANDLE handle = NULL;
	QUERYFULLPROCESSIMAGENAME query_full_process_image_name = NULL;

	handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE,
	                     entry.th32ProcessID);

	if (handle == NULL && GetLastError() == ERROR_ACCESS_DENIED) {
		handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
		                     entry.th32ProcessID);
	}

	if (handle == NULL) {
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		log_warn("Could not open process with ID %u: %s (%d)",
		         (uint32_t)entry.th32ProcessID, get_errno_name(rc), rc);

		return -1;
	}

	query_full_process_image_name =
	  (QUERYFULLPROCESSIMAGENAME)GetProcAddress(GetModuleHandle("kernel32"),
	                                            "QueryFullProcessImageNameA");

	if (query_full_process_image_name != NULL) {
		if (query_full_process_image_name(handle, 0, buffer, &length) == 0) {
			rc = ERRNO_WINAPI_OFFSET + GetLastError();

			log_warn("Could not get image name of process with ID %u: %s (%d)",
			         (uint32_t)entry.th32ProcessID, get_errno_name(rc), rc);

			return -1;
		}
	} else {
		memcpy(buffer, entry.szExeFile, length);
		buffer[length - 1] = '\0';
	}

	CloseHandle(handle);

	return 0;
}
예제 #18
0
static void program_scheduler_handle_process_state_change(void *opaque) {
	ProgramScheduler *program_scheduler = opaque;
	Program *program = containerof(program_scheduler, Program, scheduler);
	bool spawn = false;

	if (program_scheduler->state != PROGRAM_SCHEDULER_STATE_RUNNING) {
		return;
	}

	if (program_scheduler->last_spawned_process->state == PROCESS_STATE_EXITED) {
		if (program_scheduler->last_spawned_process->exit_code == 0) {
			if (program->config.start_mode == PROGRAM_START_MODE_ALWAYS) {
				spawn = true;
			}
		} else {
			if (program->config.continue_after_error) {
				if (program->config.start_mode == PROGRAM_START_MODE_ALWAYS) {
					spawn = true;
				}
			} else {
				program_scheduler_stop(program_scheduler, NULL);
			}
		}
	} else if (program_scheduler->last_spawned_process->state == PROCESS_STATE_ERROR ||
	           program_scheduler->last_spawned_process->state == PROCESS_STATE_KILLED) {
		if (program->config.continue_after_error) {
			if (program->config.start_mode == PROGRAM_START_MODE_ALWAYS) {
				spawn = true;
			}
		} else {
			program_scheduler_stop(program_scheduler, NULL);
		}
	}

	if (spawn) {
		// delay next process spawn by 1 second to avoid running into a tight
		// loop of process spawn and process exit events which would basically
		// stop redapid from doing anything else. also if the throughput between
		// redapid and brickv is low then sending to many program-process-spawned
		// callbacks might force brickv into doing nothing else but updating
		// the last-spawned-program-process information
		if (timer_configure(&program_scheduler->timer, 1000000, 0) < 0) {
			program_scheduler_handle_error(program_scheduler, false,
			                               "Could not start timer: %s (%d)",
			                               get_errno_name(errno), errno);

			return;
		}

		log_debug("Started timer for program object (identifier: %s)",
		          program->identifier->buffer);

		program_scheduler->timer_active = true;
	}
}
예제 #19
0
파일: red_stack.c 프로젝트: vszurma/brickd
// Get "red_stack_dispatch_from_spi" called from main brickd event thread
static int red_stack_spi_request_dispatch_response_event(void) {
	eventfd_t ev = 1;

	if (eventfd_write(_red_stack_notification_event, ev) < 0) {
		log_error("Could not write to red stack spi notification event: %s (%d)",
		          get_errno_name(errno), errno);

		return -1;
	}

	return 0;
}
예제 #20
0
int event_stop_platform(void) {
	uint8_t byte = 0;

	if (pipe_write(&_stop_pipe, &byte, sizeof(byte)) < 0) {
		log_error("Could not write to stop pipe: %s (%d)",
		          get_errno_name(errno), errno);

		return -1;
	}

	return 0;
}
예제 #21
0
파일: client.c 프로젝트: tewdreyer/brickd
int client_create(Client *client, EventHandle socket,
                  struct sockaddr_in *address, socklen_t length) {
	log_debug("Creating client from socket (handle: %d)", socket);

	client->socket = socket;
	client->packet_used = 0;

	// create pending request array
	if (array_create(&client->pending_requests, 32,
	                 sizeof(PacketHeader), 1) < 0) {
		log_error("Could not create pending request array: %s (%d)",
		          get_errno_name(errno), errno);

		return -1;
	}

	// get peer name
	client->peer = resolve_address(address, length);

	if (client->peer == NULL) {
		log_warn("Could not get peer name of client (socket: %d): %s (%d)",
		         socket, get_errno_name(errno), errno);

		client->peer = (char *)_unknown_peer_name;
	}

	// add socket as event source
	if (event_add_source(client->socket, EVENT_SOURCE_TYPE_GENERIC, EVENT_READ,
	                     client_handle_receive, client) < 0) {
		if (client->peer != _unknown_peer_name) {
			free(client->peer);
		}

		array_destroy(&client->pending_requests, NULL);

		return -1;
	}

	return 0;
}
예제 #22
0
void log_init_platform(void) {
	int rc;

	_event_log = RegisterEventSource(NULL, "Brick Daemon");

	if (_event_log == NULL) {
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		// this will go to the logfile if it is enabled via --debug
		log_error("Could not open Windows event log: %s (%d)",
		          get_errno_name(rc), rc);
	}
}
예제 #23
0
int hardware_init(void) {
	log_debug("Initializing hardware subsystem");

	// create stack array
	if (array_create(&_stacks, 32, sizeof(Stack *), true) < 0) {
		log_error("Could not create stack array: %s (%d)",
		          get_errno_name(errno), errno);

		return -1;
	}

	return 0;
}
예제 #24
0
static void iokit_forward_notifications(void *opaque) {
	uint8_t byte;

	(void)opaque;

	if (pipe_read(&_notification_pipe, &byte, sizeof(byte)) < 0) {
		log_error("Could not read from notification pipe: %s (%d)",
		          get_errno_name(errno), errno);

		return;
	}

	usb_reopen();
}
예제 #25
0
int hardware_add_stack(Stack *stack) {
	Stack **new_stack = array_append(&_stacks);

	if (new_stack == NULL) {
		log_error("Could not append to stack array: %s (%d)",
		          get_errno_name(errno), errno);

		return -1;
	}

	*new_stack = stack;

	return 0;
}
예제 #26
0
파일: client.c 프로젝트: tewdreyer/brickd
int client_dispatch_packet(Client *client, Packet *packet, int force) {
	int i;
	Packet *pending_request;
	int found = -1;
	int rc = -1;

	if (!force) {
		for (i = 0; i < client->pending_requests.count; ++i) {
			pending_request = array_get(&client->pending_requests, i);

			if (pending_request->header.uid == packet->header.uid &&
			    pending_request->header.function_id == packet->header.function_id &&
			    pending_request->header.sequence_number == packet->header.sequence_number) {
				found = i;

				break;
			}
		}
	}

	if (force || found >= 0) {
		if (socket_send(client->socket, packet, packet->header.length) < 0) {
			log_error("Could not send response to client (socket: %d, peer: %s): %s (%d)",
			          client->socket, client->peer, get_errno_name(errno), errno);

			goto cleanup;
		}

		if (force) {
			log_debug("Forced to sent response to client (socket: %d, peer: %s)",
			          client->socket, client->peer);
		} else {
			log_debug("Sent response to client (socket: %d, peer: %s)",
			          client->socket, client->peer);
		}
	}

	rc = 0;

cleanup:
	if (found >= 0) {
		array_remove(&client->pending_requests, found, NULL);

		if (rc == 0) {
			rc = 1;
		}
	}

	return rc;
}
예제 #27
0
int libusb_submit_transfer(struct libusb_transfer *transfer) {
	usbi_transfer *itransfer = (usbi_transfer *)transfer;
	libusb_device_handle *dev_handle = transfer->dev_handle;
	libusb_context *ctx = dev_handle->dev->ctx;
	usbfs_urb *urb = &itransfer->urb;
	int rc;

	if (transfer->type != LIBUSB_TRANSFER_TYPE_BULK ||
		transfer->timeout != 0 || transfer->callback == NULL) {
		return LIBUSB_ERROR_INVALID_PARAM;
	}

	if (itransfer->submitted) {
		return LIBUSB_ERROR_BUSY;
	}

	libusb_ref_device(dev_handle->dev);

	itransfer->submitted = true;

	urb->status = INT32_MIN;
	urb->endpoint = transfer->endpoint;
	urb->buffer = transfer->buffer;
	urb->buffer_length = transfer->length;

	rc = ioctl(dev_handle->pollfd.fd, IOCTL_USBFS_SUBMITURB, urb);

	if (rc < 0) {
		if (errno == ENODEV) {
			rc = LIBUSB_ERROR_NO_DEVICE;
		} else {
			rc = LIBUSB_ERROR_IO;
		}

		itransfer->submitted = false;

		libusb_unref_device(dev_handle->dev);

		usbi_log_error(ctx, "Could not submit %s transfer %p (length: %d): %s (%d)",
		               (LIBUSB_ENDPOINT_IN & transfer->endpoint) != 0 ? "read" : "write",
		               transfer, transfer->length, get_errno_name(errno), errno);

		return rc;
	}

	node_insert_before(&dev_handle->itransfer_sentinel, &itransfer->node);

	return LIBUSB_SUCCESS;
}
예제 #28
0
static void socat_handle_receive(void *opaque) {
	Socat *socat = opaque;
	int length;

	length = socket_receive(socat->socket,
	                        (uint8_t *)&socat->notification + socat->notification_used,
	                        sizeof(CronNotification) - socat->notification_used);

	if (length == 0) {
		log_debug("Socat (handle: %d) disconnected by peer", socat->socket->handle);

		socat->disconnected = true;

		return;
	}

	if (length < 0) {
		if (errno_interrupted()) {
			log_debug("Receiving from socat (handle: %d) was interrupted, retrying",
			          socat->socket->handle);
		} else if (errno_would_block()) {
			log_debug("Receiving from socat (handle: %d) Daemon would block, retrying",
			          socat->socket->handle);
		} else {
			log_error("Could not receive from socat (handle: %d), disconnecting socat: %s (%d)",
			          socat->socket->handle, get_errno_name(errno), errno);

			socat->disconnected = true;
		}

		return;
	}

	socat->notification_used += length;

	if (socat->notification_used < (int)sizeof(CronNotification)) {
		// wait for complete request
		return;
	}

	cron_handle_notification(&socat->notification);

	log_debug("Socat (handle: %d) received complete request, disconnecting socat",
	          socat->socket->handle);

	socat->disconnected = true;
}
예제 #29
0
파일: red_stack.c 프로젝트: vszurma/brickd
// New packet from SPI stack is send into brickd event loop
static void red_stack_dispatch_from_spi(void *opaque) {
	eventfd_t ev;

	(void)opaque;

	if (eventfd_read(_red_stack_notification_event, &ev) < 0) {
		log_error("Could not read from SPI notification event: %s (%d)",
		          get_errno_name(errno), errno);

		return;
	}

	// Send message into brickd dispatcher
	// and allow SPI thread to run again.
	network_dispatch_response(&_red_stack.packet_from_spi);
	semaphore_release(&_red_stack_dispatch_packet_from_spi_semaphore);
}
예제 #30
0
int libusb_release_interface(libusb_device_handle *dev_handle, int interface_number) {
	libusb_context *ctx = dev_handle->dev->ctx;
	int rc = ioctl(dev_handle->pollfd.fd, IOCTL_USBFS_RELEASEINTF, &interface_number);

	if (rc < 0) {
		if (errno == ENODEV) {
			return LIBUSB_ERROR_NO_DEVICE;
		} else {
			usbi_log_error(ctx, "Could not release interface %d: %s (%d)",
			               interface_number, get_errno_name(errno), errno);

			return LIBUSB_ERROR_OTHER;
		}
	}

	return LIBUSB_SUCCESS;
}