Example #1
0
File: help.c Project: pexip/os-dpkg
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;
}
Example #2
0
File: help.c Project: pexip/os-dpkg
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;
}
Example #3
0
File: help.c Project: pexip/os-dpkg
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;
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
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;
}
Example #7
0
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;
}
Example #8
0
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;
}
Example #9
0
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;
}
Example #10
0
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;
}
Example #11
0
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);
}
Example #12
0
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);
}
Example #13
0
/**
 * 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;
}
Example #14
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;
}
Example #15
0
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;
}
Example #16
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;
}
Example #17
0
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;
}
Example #18
0
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;
}
Example #19
0
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;
}
Example #20
0
void ihome_command_destroy()
{
	command_destroy(ihome_command_head);
}
Example #21
0
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);
}
Example #22
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();

}
Example #23
0
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;
}
Example #24
0
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;
}
Example #25
0
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;
}
Example #26
0
void command_free (Command* self) {
	command_destroy (self);
	g_free (self);
}