/*! Register log notification stream * @param[in] h Clicon handle * @param[in] stream Event stream. CLICON is predefined, others are application-defined * @param[in] filter Filter. For xml notification ie xpath: .[name="kalle"] * @param[in] status 0 for stop, 1 to start * @param[in] fn Callback function called when notification occurs * @param[in] arg Argument to function note * Note this calls cligen_regfd which may callback on cli command interpretator */ int cli_notification_register(clicon_handle h, char *stream, enum format_enum format, char *filter, int status, int (*fn)(int, void*), void *arg) { int retval = -1; char *logname = NULL; void *p; int s; clicon_hash_t *cdat = clicon_data(h); size_t len; int s_exist = -1; len = strlen("log_socket_") + strlen(stream) + 1; if ((logname = malloc(len)) == NULL){ clicon_err(OE_UNIX, errno, "malloc"); goto done; } snprintf(logname, len, "log_socket_%s", stream); if ((p = hash_value(cdat, logname, &len)) != NULL) s_exist = *(int*)p; if (status){ /* start */ if (s_exist!=-1){ clicon_err(OE_PLUGIN, 0, "Result log socket already exists"); goto done; } if (clicon_rpc_create_subscription(h, stream, filter, &s) < 0) goto done; if (cligen_regfd(s, fn, arg) < 0) goto done; if (hash_add(cdat, logname, &s, sizeof(s)) == NULL) goto done; } else{ /* stop */ if (s_exist != -1){ cligen_unregfd(s_exist); } hash_del(cdat, logname); #if 0 /* cant turn off */ if (clicon_rpc_create_subscription(h, status, stream, format, filter, NULL) < 0) goto done; #endif } retval = 0; done: if (logname) free(logname); return retval; }
/* * Deallocate handle. * Includes freeing options. */ int clicon_handle_exit(clicon_handle h) { struct clicon_handle *ch = handle(h); clicon_hash_t *copt; clicon_hash_t *data; if ((copt = clicon_options(h)) != NULL) hash_free(copt); if ((data = clicon_data(h)) != NULL) hash_free(data); free(ch); return 0; }