int maintainer_script_new(struct pkginfo *pkg, const char *scriptname, const char *desc, const char *cidir, char *cidirrest, ...) { struct command cmd; struct stat stab; va_list args; char buf[100]; strcpy(cidirrest, scriptname); sprintf(buf, _("new %s script"), desc); va_start(args, cidirrest); command_init(&cmd, cidir, buf); command_add_arg(&cmd, scriptname); command_add_argv(&cmd, args); va_end(args); if (stat(cidir,&stab)) { command_destroy(&cmd); if (errno == ENOENT) { debug(dbg_scripts,"maintainer_script_new nonexistent %s `%s'",scriptname,cidir); return 0; } ohshite(_("unable to stat %s `%.250s'"), buf, cidir); } do_script(pkg, &pkg->available, &cmd, &stab, 0); command_destroy(&cmd); post_script_tasks(); return 1; }
static int vmaintainer_script_installed(struct pkginfo *pkg, const char *scriptname, const char *desc, va_list args) { struct command cmd; const char *scriptpath; struct stat stab; char buf[100]; scriptpath = pkgadminfile(pkg, &pkg->installed, scriptname); sprintf(buf, _("installed %s script"), desc); command_init(&cmd, scriptpath, buf); command_add_arg(&cmd, scriptname); command_add_argv(&cmd, args); if (stat(scriptpath,&stab)) { command_destroy(&cmd); if (errno == ENOENT) { debug(dbg_scripts, "vmaintainer_script_installed nonexistent %s", scriptname); return 0; } ohshite(_("unable to stat %s `%.250s'"), buf, scriptpath); } do_script(pkg, &pkg->installed, &cmd, &stab, 0); command_destroy(&cmd); return 1; }
int maintainer_script_alternative(struct pkginfo *pkg, const char *scriptname, const char *desc, const char *cidir, char *cidirrest, const char *ifok, const char *iffallback) { struct command cmd; const char *oldscriptpath; struct stat stab; char buf[100]; oldscriptpath = pkgadminfile(pkg, &pkg->installed, scriptname); sprintf(buf, _("old %s script"), desc); command_init(&cmd, oldscriptpath, buf); command_add_args(&cmd, scriptname, ifok, versiondescribe(&pkg->available.version, vdew_nonambig), NULL); if (stat(oldscriptpath,&stab)) { if (errno == ENOENT) { debug(dbg_scripts,"maintainer_script_alternative nonexistent %s `%s'", scriptname,oldscriptpath); command_destroy(&cmd); return 0; } warning(_("unable to stat %s '%.250s': %s"), cmd.name, oldscriptpath, strerror(errno)); } else { if (!do_script(pkg, &pkg->installed, &cmd, &stab, PROCWARN)) { command_destroy(&cmd); post_script_tasks(); return 1; } } fprintf(stderr, _("dpkg - trying script from the new package instead ...\n")); strcpy(cidirrest,scriptname); sprintf(buf, _("new %s script"), desc); command_destroy(&cmd); command_init(&cmd, cidir, buf); command_add_args(&cmd, scriptname, iffallback, versiondescribe(&pkg->installed.version, vdew_nonambig), NULL); if (stat(cidir,&stab)) { command_destroy(&cmd); if (errno == ENOENT) ohshit(_("there is no script in the new version of the package - giving up")); else ohshite(_("unable to stat %s `%.250s'"),buf,cidir); } do_script(pkg, &pkg->available, &cmd, &stab, 0); fprintf(stderr, _("dpkg: ... it looks like that went OK.\n")); command_destroy(&cmd); post_script_tasks(); return 1; }
static gboolean disconnect_timeout(gpointer data) { struct _GAttrib *attrib = data; struct command *c; g_attrib_ref(attrib); c = g_queue_pop_head(attrib->requests); if (c == NULL) goto done; if (c->func) c->func(ATT_ECODE_TIMEOUT, NULL, 0, c->user_data); command_destroy(c); while ((c = g_queue_pop_head(attrib->requests))) { if (c->func) c->func(ATT_ECODE_ABORTED, NULL, 0, c->user_data); command_destroy(c); } done: attrib->stale = true; g_attrib_unref(attrib); return FALSE; }
int command_init(struct command_head_t **cmd_head) { struct command_head_t *head; struct argv_kit_t *argv_kit; argv_kit = xmalloc(sizeof(struct argv_kit_t)); argv_kit->buf = xmalloc(max_argv_buf_size); argv_kit->argv = xmalloc(sizeof(char *) * max_argc); argv_kit->argc = 0; argv_kit->alloced = max_argc; head = xmalloc(sizeof(struct command_head_t)); head->argv_kit = argv_kit; head->user = NULL; head->sys = NULL; head->output = command_default_output; head->output_buf = xmalloc(max_output_buf_size);; command_lock_init(head->lock); if (command_sys_install(head)) { command_destroy(head); return -1; } *cmd_head = head; return 0; }
static void destruct_esqlite_connection(ErlNifEnv *env, void *arg) { esqlite_connection *db = (esqlite_connection *) arg; esqlite_command *cmd = command_create(); /* Send the stop command */ cmd->type = cmd_stop; queue_push(db->commands, cmd); /* Wait for the thread to finish */ enif_thread_join(db->tid, NULL); enif_thread_opts_destroy(db->opts); /* The thread has finished... now remove the command queue, and close * the database (if it was still open). */ while(queue_has_item(db->commands)) { command_destroy(queue_pop(db->commands)); } queue_destroy(db->commands); sqlite3_close_v2(db->db); db->db = NULL; }
static gboolean cancel_all_per_queue(GQueue *queue) { struct command *c, *head = NULL; gboolean first = TRUE; if (queue == NULL) return FALSE; while ((c = g_queue_pop_head(queue))) { if (first && c->sent) { /* If the command was sent ignore its callback ... */ c->func = NULL; head = c; continue; } first = FALSE; command_destroy(c); } if (head) { /* ... and put it back in the queue */ g_queue_push_head(queue, head); } return TRUE; }
gboolean g_attrib_cancel_all(GAttrib *attrib) { struct command *c, *head = NULL; gboolean first = TRUE; if (attrib == NULL || attrib->queue == NULL) return FALSE; while ((c = g_queue_pop_head(attrib->queue))) { if (first && c->sent) { /* If the command was sent ignore its callback ... */ c->func = NULL; head = c; continue; } first = FALSE; command_destroy(c); } if (head) { /* ... and put it back in the queue */ g_queue_push_head(attrib->queue, head); } return TRUE; }
gboolean g_attrib_cancel(GAttrib *attrib, guint id) { GList *l = NULL; struct command *cmd; GQueue *queue; if (attrib == NULL) return FALSE; queue = attrib->requests; if (queue) l = g_queue_find_custom(queue, GUINT_TO_POINTER(id), command_cmp_by_id); if (l == NULL) { queue = attrib->responses; if (!queue) return FALSE; l = g_queue_find_custom(queue, GUINT_TO_POINTER(id), command_cmp_by_id); } if (l == NULL) return FALSE; cmd = l->data; if (cmd == g_queue_peek_head(queue) && cmd->sent) cmd->func = NULL; else { g_queue_remove(queue, cmd); command_destroy(cmd); } return TRUE; }
static gboolean can_write_data(GIOChannel *io, GIOCondition cond, gpointer data) { struct _GAttrib *attrib = data; struct command *cmd; GError *gerr = NULL; gsize len; GIOStatus iostat; GQueue *queue; if (attrib->stale) return FALSE; if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) return FALSE; queue = attrib->responses; cmd = g_queue_peek_head(queue); if (cmd == NULL) { queue = attrib->requests; cmd = g_queue_peek_head(queue); } if (cmd == NULL) return FALSE; /* * Verify that we didn't already send this command. This can only * happen with elementes from attrib->requests. */ if (cmd->sent) return FALSE; iostat = g_io_channel_write_chars(io, (char *) cmd->pdu, cmd->len, &len, &gerr); if (iostat != G_IO_STATUS_NORMAL) { if (gerr) { printf("%s", gerr->message); g_error_free(gerr); } return FALSE; } if (cmd->expected == 0) { g_queue_pop_head(queue); command_destroy(cmd); return TRUE; } cmd->sent = true; if (attrib->timeout_watch == 0) attrib->timeout_watch = g_timeout_add_seconds(GATT_TIMEOUT, disconnect_timeout, attrib); return FALSE; }
static void attrib_destroy(GAttrib *attrib) { GSList *l; struct command *c; while ((c = g_queue_pop_head(attrib->requests))) command_destroy(c); while ((c = g_queue_pop_head(attrib->responses))) command_destroy(c); g_queue_free(attrib->requests); attrib->requests = NULL; g_queue_free(attrib->responses); attrib->responses = NULL; for (l = attrib->events; l; l = l->next) event_destroy(l->data); g_slist_free(attrib->events); attrib->events = NULL; if (attrib->timeout_watch > 0) g_source_remove(attrib->timeout_watch); if (attrib->write_watch > 0) g_source_remove(attrib->write_watch); if (attrib->read_watch > 0) g_source_remove(attrib->read_watch); if (attrib->io) g_io_channel_unref(attrib->io); g_free(attrib->buf); if (attrib->destroy) attrib->destroy(attrib->destroy_user_data); g_free(attrib); }
void bank_destroy(bank_t *bank) { command_t *cur = bank->first; command_t *tmp; while (cur) { tmp = cur->next; command_destroy(cur); cur = tmp; } if (bank->jsr_offsets) free(bank->jsr_offsets); free(bank); }
/** * int expression_cmd_pop(expression_t *expr) * * Removes the last command structure in the given expression's command * array. If the command array is empty this function will be * unsuccessful. * * Returns 0 if successful, -1 if unsuccessful. */ int expression_cmd_pop(expression_t *expr) { int index = expr->num_cmds - 1; if (index < 0) { return -1; } command_destroy(expr->cmds[index]); expr->cmds[index] = NULL; expr->num_cmds--; return 0; }
static esqlite_command * command_create() { esqlite_command *cmd = (esqlite_command *) enif_alloc(sizeof(esqlite_command)); if(cmd == NULL) return NULL; cmd->env = enif_alloc_env(); if(cmd->env == NULL) { command_destroy(cmd); return NULL; } cmd->type = cmd_unknown; cmd->ref = 0; cmd->arg = 0; cmd->stmt = NULL; return cmd; }
int input_parse_data(input_t* input, int fd) { char buf[BUFFER_SIZE]; command_t cmd; int size = 0; for(;;) { memset(buf, 0, BUFFER_SIZE); size = recv(fd, buf, BUFFER_SIZE, MSG_PEEK); if (size <= 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { errno = 0; continue; } close(fd); return 0; } int z = parse_line(buf, &cmd); if (z == -1) { fprintf(stderr, "invalid data: '%s'\n", buf); z = strlen(buf) + 1; } else { if (cmd.type == CMD_QUIT) { input->running = 0; return 1; } cmd.fd = fd; input->callback(&cmd, input->callback_param); } command_destroy(&cmd); recv(fd, buf, z, 0); } return 0; }
static void * esqlite_connection_run(void *arg) { esqlite_connection *db = (esqlite_connection *) arg; esqlite_command *cmd; int continue_running = 1; db->alive = 1; while(continue_running) { cmd = queue_pop(db->commands); if(cmd->type == cmd_stop) continue_running = 0; else enif_send(NULL, &cmd->pid, cmd->env, make_answer(cmd, evaluate_command(cmd, db))); command_destroy(cmd); } db->alive = 0; return NULL; }
static void * esqlite_connection_run(void *arg) { esqlite_connection *db = (esqlite_connection *) arg; esqlite_command *cmd; int continue_running = 1; while(continue_running) { cmd = queue_pop(db->commands); if(cmd->type == cmd_stop) { continue_running = 0; } else if(cmd->type == cmd_notification) { enif_send(NULL, &db->notification_pid, cmd->env, cmd->arg); } else { enif_send(NULL, &cmd->pid, cmd->env, make_answer(cmd, evaluate_command(cmd, db))); } command_destroy(cmd); } return NULL; }
gboolean g_attrib_cancel(GAttrib *attrib, guint id) { GList *l; struct command *cmd; if (attrib == NULL || attrib->queue == NULL) return FALSE; l = g_queue_find_custom(attrib->queue, GUINT_TO_POINTER(id), command_cmp_by_id); if (l == NULL) return FALSE; cmd = l->data; if (cmd == g_queue_peek_head(attrib->queue) && cmd->sent) cmd->func = NULL; else { g_queue_remove(attrib->queue, cmd); command_destroy(cmd); } return TRUE; }
static gboolean can_write_data(GIOChannel *io, GIOCondition cond, gpointer data) { struct _GAttrib *attrib = data; struct command *cmd; GError *gerr = NULL; gsize len; GIOStatus iostat; if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) return FALSE; cmd = g_queue_peek_head(attrib->queue); if (cmd == NULL) return FALSE; iostat = g_io_channel_write_chars(io, (gchar *) cmd->pdu, cmd->len, &len, &gerr); if (iostat != G_IO_STATUS_NORMAL) return FALSE; if (cmd->expected == 0) { g_queue_pop_head(attrib->queue); command_destroy(cmd); return TRUE; } cmd->sent = TRUE; if (attrib->timeout_watch == 0) attrib->timeout_watch = g_timeout_add_seconds(GATT_TIMEOUT, disconnect_timeout, attrib); return FALSE; }
void ihome_command_destroy() { command_destroy(ihome_command_head); }
int main(int argc, char *argv[]) { char buf[1024]; int i; #ifdef TIOCGWINSZ struct winsize ws; if (ioctl(fileno(stdout), TIOCGWINSZ, &ws) == 0 && ws.ws_col > 0) TERMWIDTH = ws.ws_col; #endif /* Start handling the arguments. * monetdb [monetdb_options] command [options] [database [...]] * this means we first scout for monetdb_options which stops as soon * as we find a non-option argument, which then must be command */ /* first handle the simple no argument case */ if (argc <= 1) { command_help(0, NULL); return(1); } /* handle monetdb_options */ for (i = 1; argc > i && argv[i][0] == '-'; i++) { switch (argv[i][1]) { case 'v': command_version(); return(0); case 'q': monetdb_quiet = 1; break; case 'h': if (strlen(&argv[i][2]) > 0) { mero_host = &argv[i][2]; } else { if (i + 1 < argc) { mero_host = argv[++i]; } else { fprintf(stderr, "monetdb: -h needs an argument\n"); return(1); } } break; case 'p': if (strlen(&argv[i][2]) > 0) { mero_port = atoi(&argv[i][2]); } else { if (i + 1 < argc) { mero_port = atoi(argv[++i]); } else { fprintf(stderr, "monetdb: -p needs an argument\n"); return(1); } } break; case 'P': /* take care we remove the password from argv so it * doesn't show up in e.g. ps -ef output */ if (strlen(&argv[i][2]) > 0) { mero_pass = strdup(&argv[i][2]); memset(&argv[i][2], 0, strlen(mero_pass)); } else { if (i + 1 < argc) { mero_pass = strdup(argv[++i]); memset(argv[i], 0, strlen(mero_pass)); } else { fprintf(stderr, "monetdb: -P needs an argument\n"); return(1); } } break; case '-': /* skip -- */ if (argv[i][2] == '\0') break; if (strcmp(&argv[i][2], "version") == 0) { command_version(); return(0); } else if (strcmp(&argv[i][2], "help") == 0) { command_help(0, NULL); return(0); } default: fprintf(stderr, "monetdb: unknown option: %s\n", argv[i]); command_help(0, NULL); return(1); break; } } /* check consistency of -h -p and -P args */ if (mero_pass != NULL && (mero_host == NULL || *mero_host == '/')) { fprintf(stderr, "monetdb: -P requires -h to be used with a TCP hostname\n"); exit(1); } else if (mero_host != NULL && *mero_host != '/' && mero_pass == NULL) { fprintf(stderr, "monetdb: -h requires -P to be used\n"); exit(1); } /* see if we still have arguments at this stage */ if (i >= argc) { command_help(0, NULL); return(1); } /* commands that do not need merovingian to be running */ if (strcmp(argv[i], "help") == 0) { command_help(argc - i, &argv[i]); return(0); } else if (strcmp(argv[i], "version") == 0) { command_version(); return(0); } /* use UNIX socket if no hostname given */ if (mero_host == NULL || *mero_host == '/') { /* a socket looks like /tmp/.s.merovingian.<tcpport>, try * finding such port. If mero_host is set, it is the location * where we should search, which defaults to '/tmp' */ if (mero_host == NULL) mero_host = "/tmp"; /* first try the port given (or else its default) */ snprintf(buf, sizeof(buf), "%s/.s.merovingian.%d", mero_host, mero_port == -1 ? 50000 : mero_port); if (control_ping(buf, -1, NULL) == 0) { mero_host = buf; } else { /* if port wasn't given, we can try and search * for available sockets */ if (mero_port == -1) { DIR *d; struct dirent *e; struct stat s; d = opendir(mero_host); if (d == NULL) { fprintf(stderr, "monetdb: cannot find a control socket, use -h and/or -p\n"); exit(1); } while ((e = readdir(d)) != NULL) { if (strncmp(e->d_name, ".s.merovingian.", 15) != 0) continue; snprintf(buf, sizeof(buf), "%s/%s", mero_host, e->d_name); if (stat(buf, &s) == -1) continue; if (S_ISSOCK(s.st_mode)) { if (control_ping(buf, -1, NULL) == 0) { mero_host = buf; break; } } } closedir(d); } } if (mero_host != buf) { fprintf(stderr, "monetdb: cannot find a control socket, use -h and/or -p\n"); exit(1); } /* don't confuse control_send lateron */ mero_port = -1; } /* for TCP connections */ if (mero_host != NULL && *mero_host != '/' && mero_port == -1) mero_port = 50000; /* handle regular commands */ if (strcmp(argv[i], "create") == 0) { command_create(argc - i, &argv[i]); } else if (strcmp(argv[i], "destroy") == 0) { command_destroy(argc - i, &argv[i]); } else if (strcmp(argv[i], "lock") == 0) { command_lock(argc - i, &argv[i]); } else if (strcmp(argv[i], "release") == 0) { command_release(argc - i, &argv[i]); } else if (strcmp(argv[i], "status") == 0) { command_status(argc - i, &argv[i]); } else if (strcmp(argv[i], "start") == 0) { command_startstop(argc - i, &argv[i], START); } else if (strcmp(argv[i], "stop") == 0) { command_startstop(argc - i, &argv[i], STOP); } else if (strcmp(argv[i], "kill") == 0) { command_startstop(argc - i, &argv[i], KILL); } else if (strcmp(argv[i], "set") == 0) { command_set(argc - i, &argv[i], SET); } else if (strcmp(argv[i], "get") == 0) { command_get(argc - i, &argv[i]); } else if (strcmp(argv[i], "inherit") == 0) { command_set(argc - i, &argv[i], INHERIT); } else if (strcmp(argv[i], "discover") == 0) { command_discover(argc - i, &argv[i]); } else { fprintf(stderr, "monetdb: unknown command: %s\n", argv[i]); command_help(0, NULL); } if (mero_pass != NULL) free(mero_pass); return(0); }
void test_parsing(void) { struct external_command *ext_command = NULL; contact *created_contact = NULL; contact *fetched_contact = NULL; const char *cmdstr = "[1234567890] ADD_HOST_COMMENT;my_host;0;15;this is my comment, there are many like it but this one is mine"; registered_commands_init(20); { g_clear_error(&error); ok(NULL == command_parse(cmdstr, COMMAND_SYNTAX_NOKV, &error), "We can't parse commands when none are registered"); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_UNKNOWN_COMMAND), "The error code looks like expected"); ext_command = command_create("ADD_HOST_COMMENT", test__add_host_comment_handler, "This is a description for a command named ADD_HOST_COMMENT", NULL); command_argument_add(ext_command, "host", STRING, NULL, NULL); b_val = 0; command_argument_add(ext_command, "persistent", BOOL, &b_val, NULL); i_val = 42; command_argument_add(ext_command, "author", INTEGER, &i_val, NULL); s_val = "No comment"; command_argument_add(ext_command, "comment", STRING, s_val, NULL); command_register(ext_command, -1); g_clear_error(&error); ext_command = command_parse("[] UNKNOWN_COMMAND", COMMAND_SYNTAX_NOKV, &error); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_MALFORMED_COMMAND), "Malformed command error is raised for malformed commands"); ok(NULL == ext_command, "No command returned for malformed command"); g_clear_error(&error); ext_command = command_parse("[UNKNOWN_COMMAND", COMMAND_SYNTAX_NOKV, &error); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_MALFORMED_COMMAND), "Malformed command error is raised for malformed commands"); ok(NULL == ext_command, "No command returned for malformed command"); g_clear_error(&error); ext_command = command_parse("[139414354] UNKNOWN_COMMAND", COMMAND_SYNTAX_NOKV, &error); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_UNKNOWN_COMMAND), "Unknown command error is raised for unknown commands"); ok(NULL == ext_command, "No command returned for unknown command"); g_clear_error(&error); ext_command = command_parse(cmdstr, COMMAND_SYNTAX_NOKV, &error); ok(error == NULL, "The command parses without error"); ok(!strcmp("my_host", command_argument_get_value(ext_command, "host")), "Host value parsed successfully"); ok(0 == *(int *)command_argument_get_value(ext_command, "persistent"), "Persistent value parsed successfully"); ok(15 == *(int *)command_argument_get_value(ext_command, "author"), "Author value parsed successfully"); ok(!strcmp("this is my comment, there are many like it but this one is mine", command_argument_get_value(ext_command, "comment")), "Comment value parsed successfully"); command_destroy(ext_command); g_clear_error(&error); ext_command = command_parse("[1234567890] ADD_HOST_COMMENT;my_host;0;15;this is my newline\n, there are many like it but this one is\n m\ni\nn\ne", COMMAND_SYNTAX_NOKV, &error); ok(error == NULL, "Command containing newlines parses without error"); ok(!strcmp("this is my newline\n, there are many like it but this one is\n m\ni\nn\ne", command_argument_get_value(ext_command, "comment")), "Comment containing newlines parsed successfully"); command_destroy(ext_command); g_clear_error(&error); ext_command = command_parse(cmdstr, COMMAND_SYNTAX_NOKV, &error); ok(0 == command_execute_handler(ext_command), "Callback exit value properly passed on"); ok(!strcmp("my_host", received_host), "Host value passed to callback"); ok(0 == *received_persistent, "Persistent value passed to callback"); ok(received_entry_time == 1234567890, "Entry time passed correctly to callback"); command_destroy(ext_command); free(received_host); free(received_persistent); g_clear_error(&error); ext_command = command_parse("[1234567890] ADD_HOST_COMMENT;;1", COMMAND_SYNTAX_NOKV, &error); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_MISSING_ARG), "Missing arguments are complained about"); ok(ext_command == NULL, "No command returned for command with missing arguments"); g_clear_error(&error); ext_command = command_parse("[15341345] ADD_HOST_COMMENT", COMMAND_SYNTAX_NOKV, &error); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_MISSING_ARG), "Missing arguments are complained about (no arguments supplied)"); ok(ext_command == NULL, "No command returned for command with missing arguments"); g_clear_error(&error); ext_command = command_parse("[1234567890] ADD_HOST_COMMENT;my_host;0;441;this is my comment, there are many like it but this one is mine;Post-semi-colon stuff", COMMAND_SYNTAX_NOKV, &error); ok(error == NULL, "Last string argument may contain semi-colons"); ok(ext_command != NULL, "A command should be returned when last string-argument has semi-colons"); command_destroy(ext_command); g_clear_error(&error); ext_command = command_parse("[1234567890] ADD_HOST_COMMENT;my_host;0;Dora the Explora';this is my comment, there are many like it but this one is mine", COMMAND_SYNTAX_NOKV, &error); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_TYPE_MISMATCH), "Type errors are complained about"); ok(ext_command == NULL, "No command returned for command with argument type errors"); g_clear_error(&error); ext_command = command_parse("[1234567890] ADD_HOST_COMMENT;my_host;1;4lyfe;this is my comment, there are many like it but this one is mine", COMMAND_SYNTAX_NOKV, &error); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_TYPE_MISMATCH), "Junk characters after integer arguments are complained about"); ok(ext_command == NULL, "No command returned for command with argument type mismatch errors"); g_clear_error(&error); ext_command = command_create("ADD_HOST_COMMENT_WITH_TIMESTAMP", test__add_host_comment_handler, "This is a description for a command named ADD_HOST_COMMENT", NULL); command_argument_add(ext_command, "host", STRING, NULL, NULL); command_argument_add(ext_command, "persistent", BOOL, NULL, NULL); i_val = 42; command_argument_add(ext_command, "author", INTEGER, &i_val, NULL); s_val = "No comment"; command_argument_add(ext_command, "comment", STRING, s_val, NULL); t_val = 0; command_argument_add(ext_command, "timestamp", TIMESTAMP, &t_val, NULL); command_register(ext_command, -1); g_clear_error(&error); ext_command = command_parse("[1234567890] ADD_HOST_COMMENT_WITH_TIMESTAMP;my_host;1;441;this is my comment, there are many like it but this one is mine;1234987650", COMMAND_SYNTAX_NOKV, &error); ok(error == NULL, "No error when parsing proper commands"); ok(1234987650 == *(time_t *)command_argument_get_value(ext_command, "timestamp"), "Timestamp value parsed successfully"); command_destroy(ext_command); g_clear_error(&error); ext_command = command_parse("[1234567890] ADD_HOST_COMMENT_WITH_TIMESTAMP;my_host;4;441;this is my comment, there are many like it but this one is mine;1234987650", COMMAND_SYNTAX_NOKV, &error); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_VALIDATION_FAILURE), "Invalid BOOL value (4) is complained about"); ok(NULL == ext_command, "No command returned for command with invalid argument values"); g_clear_error(&error); ext_command = command_parse("[1234567890] ADD_HOST_COMMENT_WITH_TIMESTAMP;my_host;1;441;this is my comment, there are many like it but this one is mine;14:49", COMMAND_SYNTAX_NOKV, &error); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_TYPE_MISMATCH), "Malformed timestamp value is complained about"); ok(NULL == ext_command, "No command returned for command with argument type mismatch"); g_clear_error(&error); ext_command = command_parse("[1234567890] ADD_HOST_COMMENT_WITH_TIMESTAMP;my_host;1;441;;", COMMAND_SYNTAX_NOKV, &error); ok(error == NULL, "Missing arguments which have default values are not complained about"); ok(!strcmp("No comment", command_argument_get_value(ext_command, "comment")), "Default value is used for missing argument"); ok(t_val == *(time_t *)command_argument_get_value(ext_command, "timestamp"), "Default value is used for missing argument at end of arg string"); command_destroy(ext_command); g_clear_error(&error); ext_command = command_parse("[1234567890] ADD_HOST_COMMENT_WITH_TIMESTAMP;some_host;;441;;13485799", COMMAND_SYNTAX_NOKV, &error); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_MISSING_ARG), "Missing arguments which don't have default values are complained about"); ok(NULL == ext_command, "No command returned for command with missing argument and no default"); g_clear_error(&error); ext_command = command_create("ADD_SVC_COMMENT", test__add_service_comment_handler, "This is a description for a command named CMD_ADD_SVC_COMMENT", NULL); command_argument_add(ext_command, "service", SERVICE, NULL, NULL); command_argument_add(ext_command, "persistent", BOOL, &b_val, NULL); command_argument_add(ext_command, "author", INTEGER, &i_val, NULL); command_argument_add(ext_command, "comment", STRING, s_val, NULL); command_register(ext_command, -1); g_clear_error(&error); ext_command = command_parse("[1234567890] ADD_SVC_COMMENT;my_host;NO_SUCH_SERVICE;1;441;this is my service comment, there are many like it but this one is mine", COMMAND_SYNTAX_NOKV, &error); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_VALIDATION_FAILURE), "Invalid service is complained about"); ok(NULL == ext_command, "No command returned for command with invalid service"); g_clear_error(&error); ext_command = command_create("ADD_SVC_COMMENT_2", test__add_service_comment_handler, "This is a description for a command with a custom service validator", NULL); command_argument_add(ext_command, "service", SERVICE, NULL, custom_service_validator); command_argument_add(ext_command, "persistent", BOOL, &b_val, NULL); command_argument_add(ext_command, "author", INTEGER, &i_val, NULL); command_argument_add(ext_command, "comment", STRING, s_val, NULL); command_register(ext_command, -1); g_clear_error(&error); ext_command = command_parse("[1234567890] ADD_SVC_COMMENT_2;my_host;LETS_PRETEND_THIS_EXISTS;1;441;this is my service comment, there are many like it but this one is mine", COMMAND_SYNTAX_NOKV, &error); ok(error == NULL, "Custom validator does not decline our invalid service"); command_destroy(ext_command); g_clear_error(&error); ext_command = command_create("DEL_HOST_COMMENT", test__del_host_comment_handler, "This command is used to delete a specific host comment.", NULL); command_argument_add(ext_command, "comment_id", ULONG, NULL, NULL); command_register(ext_command, -1); g_clear_error(&error); ext_command = command_parse("[1234567890] DEL_HOST_COMMENT;10;Excess argument;snurre", COMMAND_SYNTAX_NOKV, &error); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_EXCESS_ARG), "Excess arguments are complained about"); ok(ext_command == NULL, "No command returned for commands with excess arguments"); g_clear_error(&error); ext_command = command_parse("[1234567890] DEL_HOST_COMMENT;10", COMMAND_SYNTAX_NOKV, &error); ok((unsigned long) 10 == *(unsigned long *)command_argument_get_value(ext_command, "comment_id"), "ULONG argument parsed correctly"); command_destroy(ext_command); ext_command = command_create("DEL_HOST_COMMENT_2", test__del_host_comment_handler, "This command is used to delete a specific host comment.", "int=comment_id;str=string_arg"); command_register(ext_command, -1); g_clear_error(&error); ext_command = command_parse("[1234567890] DEL_HOST_COMMENT_2;10;foobar", COMMAND_SYNTAX_NOKV, &error); ok(error == NULL, "No error when parsing command created with argspec"); ok(!strcmp("foobar", command_argument_get_value(ext_command, "string_arg")), "Can parse command created with argspec (string arg)"); ok(10 == *(int *)command_argument_get_value(ext_command, "comment_id"), "Can parse command created with argspec (int arg)"); command_destroy(ext_command); g_clear_error(&error); ext_command = command_parse("[1234567890] DEL_HOST_COMMENT_2;1;", COMMAND_SYNTAX_NOKV, &error); ok (ext_command == NULL, "Missing argument at end of arg string is complained about"); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_MISSING_ARG), "Missing argument at end of arg string raises the correct error"); g_clear_error(&error); ext_command = command_create("DISABLE_NOTIFICATIONS", test__disable_notifications_handler, "Disables host and service notifications on a program-wide basis.", NULL); command_register(ext_command, -1); ext_command = command_parse("[1234567890] DISABLE_NOTIFICATIONS", COMMAND_SYNTAX_NOKV, &error); ok(ext_command != NULL, "No problem parsing commands with no arguments (when none required)"); command_destroy(ext_command); g_clear_error(&error); ext_command = command_create("DO_THING_WITH_TIMEPERIOD", test__do_thing_with_timeperiod_handler, "Does a thing with a timeperiod", NULL); command_argument_add(ext_command, "timeperiod", TIMEPERIOD, NULL, NULL); command_register(ext_command, -1); g_clear_error(&error); ext_command = command_parse("[1234567890] DO_THING_WITH_TIMEPERIOD;24x8", COMMAND_SYNTAX_NOKV, &error); ok(ext_command == NULL, "No command returned when timeperiod arg is invalid"); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_VALIDATION_FAILURE), "Validation error raised for invalid timeperiod"); registered_timeperiod = find_timeperiod("24x7"); assert(NULL != registered_timeperiod); g_clear_error(&error); ext_command = command_parse("[1234567890] DO_THING_WITH_TIMEPERIOD;24x7", COMMAND_SYNTAX_NOKV, &error); ok(ext_command != NULL, "Command returned when timeperiod arg is not invalid"); ok(error == NULL, "Validation error not raised for valid timeperiod"); ok(registered_timeperiod == command_argument_get_value(ext_command, "timeperiod"), "The correct timeperiod is returned"); command_destroy(ext_command); /** CONTACT SETUP*/ g_clear_error(&error); ext_command = command_create("FIND_CONTACT", test__do_thing_with_contact_handler, "Does a thing with contact", NULL); command_argument_add(ext_command, "contact", CONTACT, NULL, NULL); command_register(ext_command, -1); created_contact = find_contact("nagiosadmin"); assert(NULL != created_contact); /** CONTACT TEST*/ g_clear_error(&error); ext_command = command_parse("[1234567890] FIND_CONTACT;bango", COMMAND_SYNTAX_NOKV, &error); ok(ext_command == NULL, "No command returned when contact arg is invalid"); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_VALIDATION_FAILURE), "Validation error raised for invalid contact"); /** CONTACT TEST*/ g_clear_error(&error); ext_command = command_parse("[1234567890] FIND_CONTACT;nagiosadmin", COMMAND_SYNTAX_NOKV, &error); ok(ext_command != NULL, "Command returned when contact arg is not invalid"); ok(error == NULL, "Validation error not raised for valid contact"); fetched_contact = command_argument_get_value(ext_command, "contact"); ok(created_contact->name == fetched_contact->name, "The correct contact is returned"); /** CONTACT TEARDOWN*/ command_destroy(ext_command); g_clear_error(&error); ext_command = command_parse("[1234567890] _MY_CUSTOMARILY_CUSTOM_CUSTARD_COMMAND;foo;bar;baz;33", COMMAND_SYNTAX_NOKV, &error); ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_CUSTOM_COMMAND), "Custom command reported as such"); ok(ext_command != NULL, "Raw command returned when parsing custom command"); ok(!strcmp("foo;bar;baz;33", command_raw_arguments(ext_command)), "Raw arguments properly set for custom command"); ok(command_entry_time(ext_command) == (time_t)1234567890, "Entry time set for custom command"); command_destroy(ext_command); g_clear_error(&error); } registered_commands_deinit(); }
static gboolean received_data(GIOChannel *io, GIOCondition cond, gpointer data) { struct _GAttrib *attrib = data; struct command *cmd = NULL; GSList *l; uint8_t buf[512], status; gsize len; GIOStatus iostat; gboolean qempty; if (attrib->timeout_watch > 0) { g_source_remove(attrib->timeout_watch); attrib->timeout_watch = 0; } if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) { attrib->read_watch = 0; return FALSE; } memset(buf, 0, sizeof(buf)); iostat = g_io_channel_read_chars(io, (gchar *) buf, sizeof(buf), &len, NULL); if (iostat != G_IO_STATUS_NORMAL) { status = ATT_ECODE_IO; goto done; } for (l = attrib->events; l; l = l->next) { struct event *evt = l->data; if (evt->expected == buf[0] || evt->expected == GATTRIB_ALL_EVENTS || (is_response(buf[0]) == FALSE && evt->expected == GATTRIB_ALL_REQS)) evt->func(buf, len, evt->user_data); } if (is_response(buf[0]) == FALSE) return TRUE; cmd = g_queue_pop_head(attrib->queue); if (cmd == NULL) { /* Keep the watch if we have events to report */ return attrib->events != NULL; } if (buf[0] == ATT_OP_ERROR) { status = buf[4]; goto done; } if (cmd->expected != buf[0]) { status = ATT_ECODE_IO; goto done; } status = 0; done: qempty = attrib->queue == NULL || g_queue_is_empty(attrib->queue); if (cmd) { if (cmd->func) cmd->func(status, buf, len, cmd->user_data); command_destroy(cmd); } if (!qempty) wake_up_sender(attrib); return TRUE; }
static gboolean received_data(GIOChannel *io, GIOCondition cond, gpointer data) { struct _GAttrib *attrib = data; struct command *cmd = NULL; GSList *l; uint8_t buf[512], status; gsize len; GIOStatus iostat; if (attrib->stale) return FALSE; if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) { struct command *c; while ((c = g_queue_pop_head(attrib->requests))) { if (c->func) c->func(ATT_ECODE_IO, NULL, 0, c->user_data); command_destroy(c); } attrib->read_watch = 0; return FALSE; } memset(buf, 0, sizeof(buf)); iostat = g_io_channel_read_chars(io, (char *) buf, sizeof(buf), &len, NULL); if (iostat != G_IO_STATUS_NORMAL) { status = ATT_ECODE_IO; goto done; } for (l = attrib->events; l; l = l->next) { struct event *evt = l->data; if (match_event(evt, buf, len)) evt->func(buf, len, evt->user_data); } if (!is_response(buf[0])) return TRUE; if (attrib->timeout_watch > 0) { g_source_remove(attrib->timeout_watch); attrib->timeout_watch = 0; } cmd = g_queue_pop_head(attrib->requests); if (cmd == NULL) { /* Keep the watch if we have events to report */ return attrib->events != NULL; } if (buf[0] == ATT_OP_ERROR) { status = buf[4]; goto done; } if (cmd->expected != buf[0]) { status = ATT_ECODE_IO; goto done; } status = 0; done: if (!g_queue_is_empty(attrib->requests) || !g_queue_is_empty(attrib->responses)) wake_up_sender(attrib); if (cmd) { if (cmd->func) cmd->func(status, buf, len, cmd->user_data); command_destroy(cmd); } return TRUE; }
static int ws_events_callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { struct lws_context *context = lws_get_context(wsi); ws_t *ws = lws_context_user(context); struct per_session_data__events *pss = user; int i; switch (reason) { case LWS_CALLBACK_ESTABLISHED: pss->ws = ws; pss->cmd = command_new((command_handler_t) ws_events_command, pss); buf_init(&pss->out_buf); pss->id = ws_session_add(ws, pss); log_debug(2, "ws_events_callback LWS_CALLBACK_ESTABLISHED [%04X]", pss->id); break; case LWS_CALLBACK_SERVER_WRITEABLE: i = pss->out_buf.len - LWS_SEND_BUFFER_PRE_PADDING; if (i > 0) { log_debug(2, "ws_events_callback LWS_CALLBACK_SERVER_WRITEABLE [%04X]: %d bytes", pss->id, i); buf_grow(&pss->out_buf, LWS_SEND_BUFFER_POST_PADDING); int ret = lws_write(wsi, pss->out_buf.base+LWS_SEND_BUFFER_PRE_PADDING, i, LWS_WRITE_TEXT); pss->out_buf.len = 0; if (ret < i) { log_str("HTTP ERROR: %d writing to event websocket", ret); return -1; } } else { log_debug(2, "ws_events_callback LWS_CALLBACK_SERVER_WRITEABLE [%04X]: READY", pss->id); } break; case LWS_CALLBACK_RECEIVE: log_debug(2, "ws_events_callback LWS_CALLBACK_RECEIVE [%04X]: %d bytes", pss->id, len); log_debug_data(in, len); /* Make sure send buffer has room for pre-padding */ if (pss->out_buf.len == 0) { buf_append_zero(&pss->out_buf, LWS_SEND_BUFFER_PRE_PADDING); } /* Execute command */ command_recv(pss->cmd, in, len); /* Trig response write */ lws_callback_on_writable(wsi); break; case LWS_CALLBACK_CLOSED: log_debug(2, "ws_events_callback LWS_CALLBACK_CLOSED [%04X]", pss->id); pss->ws = NULL; if (pss->cmd != NULL) { command_destroy(pss->cmd); pss->cmd = NULL; } buf_cleanup(&pss->out_buf); pss->id = -1; ws_session_remove(ws, pss); break; /* * this just demonstrates how to use the protocol filter. If you won't * study and reject connections based on header content, you don't need * to handle this callback */ case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: log_debug(2, "ws_events_callback LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION [%04X]", pss->id); ws_dump_handshake_info(wsi); /* you could return non-zero here and kill the connection */ // return -1; break; case LWS_CALLBACK_PROTOCOL_INIT: log_debug(2, "ws_events_callback LWS_CALLBACK_PROTOCOL_INIT"); break; default: log_debug(2, "ws_events_callback: reason=%d", reason); break; } return 0; }
void command_free (Command* self) { command_destroy (self); g_free (self); }