enum nss_status _nss_srvd_getaliasbyname_r(const char *name, struct aliasent *ae, char *buffer, size_t bufsize, int *ret_errno) { enum nss_status status; srvd_service_request_t request; srvd_service_response_t response; srvd_service_request_initialize(&request); srvd_protocol_packet_field_append(&request.packet, SRVD_SERVICE_NSS_ALIASES_REQUEST_NAME, (uint16_t)(sysconf(_SC_LOGIN_NAME_MAX) + 1), name); srvd_service_response_initialize(&response); srvd_service_request_query(&request, &response); if(response.status == SRVD_SERVICE_RESPONSE_NOTFOUND) { SRVD_NSS_NORECORD(status, _nss_srvd_getaliasbyname_r_error); } else if(response.status == SRVD_SERVICE_RESPONSE_UNAVAIL) { SRVD_NSS_UNAVAIL(status, _nss_srvd_getaliasbyname_r_error); } else if(response.status != SRVD_SERVICE_RESPONSE_SUCCESS) { SRVD_NSS_FAIL(status, ret_errno, NSS_STATUS_TRYAGAIN, EINVAL, _nss_srvd_getaliasbyname_r_error); } status = _srvd_nss_aliases_populate(&response, ae, buffer, bufsize, ret_errno); _nss_srvd_getaliasbyname_r_error: srvd_service_request_finalize(&request); srvd_service_response_finalize(&response); return status; }
enum nss_status _nss_srvd_getaliasent_r(struct aliasent *ae, char *buffer, size_t bufsize, int *ret_errno) { enum nss_status status; uint32_t *offset; srvd_service_request_t request; srvd_service_response_t response; SRVD_THREAD_ONCE_CALL(_srvd_nss_aliases_aliasent_initialize, _srvd_nss_aliases_aliasent_initialize_callback); if(!SRVD_THREAD_KEY_DATA_HAS(_srvd_nss_aliases_aliasent_offset)) { if(!_srvd_nss_aliases_aliasent_initialize_offset()) return NSS_STATUS_UNAVAIL; } offset = (uint32_t *)SRVD_THREAD_KEY_DATA_GET(_srvd_nss_aliases_aliasent_offset); srvd_service_request_initialize(&request); srvd_protocol_packet_field_append_uint32(&request.packet, SRVD_SERVICE_NSS_ALIASES_REQUEST_ENTITIES, *offset); srvd_service_response_initialize(&response); srvd_service_request_query(&request, &response); if(response.status == SRVD_SERVICE_RESPONSE_NOTFOUND) { SRVD_NSS_NORECORD(status, _nss_srvd_getaliasent_r_error); } else if(response.status == SRVD_SERVICE_RESPONSE_UNAVAIL) { SRVD_NSS_UNAVAIL(status, _nss_srvd_getaliasent_r_error); } else if(response.status != SRVD_SERVICE_RESPONSE_SUCCESS) { SRVD_NSS_FAIL(status, ret_errno, NSS_STATUS_TRYAGAIN, EINVAL, _nss_srvd_getaliasent_r_error); } status = _srvd_nss_aliases_populate(&response, ae, buffer, bufsize, ret_errno); (*offset)++; _nss_srvd_getaliasent_r_error: srvd_service_request_finalize(&request); srvd_service_response_finalize(&response); return status; }
srvd_boolean_t srvd_server_unsock_execute(srvd_server_unsock_t *server) { srvd_boolean_t status = SRVD_TRUE; SRVD_RETURN_FALSE_UNLESS(server); server->monitor.executing = SRVD_TRUE; if(bind(server->socket, (struct sockaddr *)&server->endpoint, sizeof(struct sockaddr_un)) == -1) { SRVD_LOG_ERROR("srvd_server_unsock_execute: Unable to bind to socket at \"%s\"", server->endpoint.sun_path); return SRVD_FALSE; } if(listen(server->socket, server->conf.queue_size) == -1) { SRVD_LOG_ERROR("srvd_server_unsock_execute: Unable to listen on bound socket"); return SRVD_FALSE; } for(;;) { int client = accept(server->socket, NULL, 0); if(client == -1) { SRVD_LOG_WARNING("srvd_server_unsock_execute: Error accept()ing client"); continue; } srvd_service_request_t request; srvd_service_response_t response; srvd_service_request_initialize(&request); srvd_service_response_initialize(&response); if(!_srvd_server_unsock_read(client, &request.packet)) { SRVD_LOG_WARNING("srvd_server_unsock_execute: Could not read data from client"); goto _srvd_server_unsock_execute_client_error; } srvd_protocol_packet_field_t *field = NULL; if(!srvd_protocol_packet_field_get_first(&request.packet, &field)) { /* Nothing valid? */ SRVD_LOG_WARNING("srvd_server_unsock_execute: Invalid packet"); goto _srvd_server_unsock_execute_client_error; } /* Okay, let's see if we have a matching handler for the request. */ srvd_server_service_handler_pt handler = NULL; if(srvd_server_service_get(&server->monitor, field->type, &handler)) { handler(&request, &response); /* Get the response status and inject it into the list of fields. */ srvd_protocol_packet_field_insert_uint16(&response.packet, SRVD_PROTOCOL_STATUS, response.status); } else /* Nope -- unavailable. */ srvd_protocol_packet_field_insert_uint16(&response.packet, SRVD_PROTOCOL_STATUS, SRVD_SERVICE_RESPONSE_UNAVAIL); if(!_srvd_server_unsock_write(client, &response.packet)) { SRVD_LOG_WARNING("srvd_server_unsock_execute: Could not write data to client"); goto _srvd_server_unsock_execute_client_error; } _srvd_server_unsock_execute_client_error: srvd_service_request_finalize(&request); srvd_service_response_finalize(&response); if(client >= 0) close(client); } close(server->socket); server->monitor.executing = SRVD_FALSE; return status; }