/** * @brief Reads complete content of a file referenced by the descriptor 'fd' into the memory. * Caller is responsible for deallocation of the memory block returned through the output argument 'out'. * Returns SR_ERR_OK in case of success, error code otherwise. */ static int srcfg_read_file_content(int fd, char **out) { int rc = SR_ERR_OK; size_t size = EXPECTED_MAX_INPUT_FILE_SIZE; unsigned cur = 0; ssize_t n = 0; char *buffer = NULL; CHECK_NULL_ARG(out); buffer = malloc(size); CHECK_NULL_NOMEM_GOTO(buffer, rc, fail); do { if (size == cur + 1) { size <<= 1; char *new_buffer = realloc(buffer, size); CHECK_NULL_NOMEM_GOTO(new_buffer, rc, fail); buffer = new_buffer; } n = read(fd, buffer + cur, size - cur - 1); CHECK_NOT_MINUS1_LOG_GOTO(n, rc, SR_ERR_INTERNAL, fail, "Read operation failed: %s.", sr_strerror_safe(errno)); cur += n; } while (0 < n); buffer[cur] = '\0'; *out = buffer; return rc; fail: free(buffer); return rc; }
/** * @brief Loads a plugin form provided filename. */ static int sr_pd_load_plugin(sr_session_ctx_t *session, const char *plugin_filename, sr_pd_plugin_ctx_t *plugin_ctx) { int rc = SR_ERR_OK; CHECK_NULL_ARG3(session, plugin_filename, plugin_ctx); plugin_ctx->filename = strdup(plugin_filename); CHECK_NULL_NOMEM_GOTO(plugin_ctx->filename, rc, cleanup); /* open the dynamic library with plugin */ plugin_ctx->dl_handle = dlopen(plugin_filename, RTLD_LAZY); if (NULL == plugin_ctx->dl_handle) { SR_LOG_WRN("Unable to load the plugin: %s.", dlerror()); rc = SR_ERR_INIT_FAILED; goto cleanup; } /* get init function pointer */ *(void **) (&plugin_ctx->init_cb) = dlsym(plugin_ctx->dl_handle, SR_PLUGIN_INIT_FN_NAME); if (NULL == plugin_ctx->init_cb) { SR_LOG_WRN("Unable to find '%s' function: %s.", SR_PLUGIN_INIT_FN_NAME, dlerror()); rc = SR_ERR_INIT_FAILED; goto cleanup; } /* get cleanup function pointer */ *(void **) (&plugin_ctx->cleanup_cb) = dlsym(plugin_ctx->dl_handle, SR_PLUGIN_CLEANUP_FN_NAME); if (NULL == plugin_ctx->cleanup_cb) { SR_LOG_WRN("Unable to find '%s' function: %s.", SR_PLUGIN_CLEANUP_FN_NAME, dlerror()); rc = SR_ERR_INIT_FAILED; goto cleanup; } /* get health check function pointer */ *(void **) (&plugin_ctx->health_check_cb) = dlsym(plugin_ctx->dl_handle, SR_PLUGIN_HEALTH_CHECK_FN_NAME); if (NULL != plugin_ctx->health_check_cb) { SR_LOG_DBG("'%s' function found, health checks will be applied.", SR_PLUGIN_HEALTH_CHECK_FN_NAME); } return SR_ERR_OK; cleanup: if (NULL != plugin_ctx->dl_handle) { dlclose(plugin_ctx->dl_handle); } free(plugin_ctx->filename); return rc; }
int cl_version_verify(sr_conn_ctx_t *connection) { int rc = SR_ERR_OK; Sr__Msg *msg_req = NULL, *msg_resp = NULL; sr_mem_ctx_t *sr_mem = NULL; /* prepare version-verification request */ rc = sr_mem_new(0, &sr_mem); CHECK_RC_MSG_GOTO(rc, cleanup, "Failed to create a new Sysrepo memory context."); rc = sr_gpb_req_alloc(sr_mem, SR__OPERATION__VERSION_VERIFY, /* undefined session id */ 0, &msg_req); CHECK_RC_MSG_GOTO(rc, cleanup, "Cannot allocate GPB message."); /* set argument */ sr_mem_edit_string(sr_mem, &msg_req->request->version_verify_req->soname, SR_COMPAT_VERSION); CHECK_NULL_NOMEM_GOTO(msg_req->request->version_verify_req->soname, rc, cleanup); /* send the request */ SR_LOG_DBG("Sending %s request.", sr_gpb_operation_name(SR__OPERATION__VERSION_VERIFY)); pthread_mutex_lock(&connection->lock); rc = cl_message_send(connection, msg_req); if (SR_ERR_OK != rc) { SR_LOG_ERR("Unable to send the message with request (operation=%s).", sr_gpb_operation_name(msg_req->request->operation)); pthread_mutex_unlock(&connection->lock); goto cleanup; } SR_LOG_DBG("%s request sent, waiting for response.", sr_gpb_operation_name(SR__OPERATION__VERSION_VERIFY)); /* receive the response */ rc = cl_message_recv(connection, &msg_resp, NULL); if (SR_ERR_OK != rc) { SR_LOG_ERR("Unable to receive the message with response (operation=%s).", sr_gpb_operation_name(msg_req->request->operation)); pthread_mutex_unlock(&connection->lock); goto cleanup; } pthread_mutex_unlock(&connection->lock); SR_LOG_DBG("%s response received, processing.", sr_gpb_operation_name(SR__OPERATION__VERSION_VERIFY)); /* validate the response */ rc = sr_gpb_msg_validate(msg_resp, SR__MSG__MSG_TYPE__RESPONSE, SR__OPERATION__VERSION_VERIFY); if (SR_ERR_OK != rc) { SR_LOG_ERR("Malformed message with response received (operation=%s).", sr_gpb_operation_name(msg_req->request->operation)); goto cleanup; } /* process the result */ if (SR_ERR_OK != msg_resp->response->result) { SR_LOG_ERR("Sysrepod's \"%s\" version is not compatible with version \""SR_COMPAT_VERSION"\" in use.", msg_resp->response->version_verify_resp->soname); rc = msg_resp->response->result; goto cleanup; } cleanup: if (NULL != msg_req) { sr_msg_free(msg_req); } else { sr_mem_free(sr_mem); } if (NULL != msg_resp) { sr_msg_free(msg_resp); } return rc; }