Exemplo n.º 1
0
int			write_instructions(int fd, int fdwrite)

{
  char			*tmp;
  int			size;
  int			i;
  char			*ins;
  char			*param;
  t_asm			*my_asm;

  i = 2;
  my_asm = NULL;
  while ((tmp = get_next_line(fd)))
    {
      i++;
      if (tmp != NULL && tmp[0] != '.' && all_space(tmp) != 0)
	{
	  tmp = remove_space(tmp);
	  ins = parse_action(tmp, 0);
	  param = parse_action(tmp, 1);
	  ins = remove_all_space(ins);
	  param = remove_all_space(param);
	  if (check_arg(ins) != 1 ||
	      check_param(ins, param) != 1)
	    return (error_line(i));
	  my_asm = add_action(my_asm, ins, param);
	}
    }
  my_asm = my_asm->next;
  if ((size = instructions_file(fdwrite, my_asm)) == -1
      || write_size(fdwrite, size) == -1)
    return (-1);
  return (0);
}
Exemplo n.º 2
0
/**
 * Init function for the powerkey component
 *
 * @return TRUE on success, FALSE on failure
 */
gboolean mce_powerkey_init(void)
{
	gboolean status = FALSE;
	gchar *tmp = NULL;

	/* Append triggers/filters to datapipes */
	append_input_trigger_to_datapipe(&keypress_pipe,
					 powerkey_trigger);

	/* req_trigger_powerkey_event */
	if (mce_dbus_handler_add(MCE_REQUEST_IF,
				 MCE_TRIGGER_POWERKEY_EVENT_REQ,
				 NULL,
				 DBUS_MESSAGE_TYPE_METHOD_CALL,
				 trigger_powerkey_event_req_dbus_cb) == NULL)
		goto EXIT;

	/* Get configuration options */
	longdelay = mce_conf_get_int(MCE_CONF_POWERKEY_GROUP,
				     MCE_CONF_POWERKEY_LONG_DELAY,
				     DEFAULT_POWER_LONG_DELAY);
	mediumdelay = mce_conf_get_int(MCE_CONF_POWERKEY_GROUP,
				       MCE_CONF_POWERKEY_MEDIUM_DELAY,
				       DEFAULT_POWER_MEDIUM_DELAY);
	tmp = mce_conf_get_string(MCE_CONF_POWERKEY_GROUP,
				  MCE_CONF_POWERKEY_SHORT_ACTION,
				  "");

	/* Since we've set a default, error handling is unnecessary */
	(void)parse_action(tmp, &shortpresssignal, &shortpressaction);
	g_free(tmp);

	tmp = mce_conf_get_string(MCE_CONF_POWERKEY_GROUP,
				  MCE_CONF_POWERKEY_LONG_ACTION,
				  "");

	/* Since we've set a default, error handling is unnecessary */
	(void)parse_action(tmp, &longpresssignal, &longpressaction);
	g_free(tmp);

	doublepressdelay = mce_conf_get_int(MCE_CONF_POWERKEY_GROUP,
					    MCE_CONF_POWERKEY_DOUBLE_DELAY,
					    DEFAULT_POWER_DOUBLE_DELAY);
	tmp = mce_conf_get_string(MCE_CONF_POWERKEY_GROUP,
				  MCE_CONF_POWERKEY_DOUBLE_ACTION,
				  "");

	/* Since we've set a default, error handling is unnecessary */
	(void)parse_action(tmp, &doublepresssignal, &doublepressaction);
	g_free(tmp);

	status = TRUE;

EXIT:
	return status;
}
Exemplo n.º 3
0
static void parse_config(const char *fn, char *s)
{
    struct parse_state state;

    next_token(&state);
    int kw = lookup_keyword(args[0]);
    parse_new_section(&state, kw, nargs, args);
    {
        // case K_service: set service handle action
        // add service into list
        state->context = parse_service(state, nargs, args);
        {
            struct service *svc;
            list_init(&svc->onrestart.commands);
            list_add_tail(&service_list, &svc->slist);
        }

        // case K_on:
        // add action into list
        state->context = parse_action(state, nargs, args);
        {
            list_add_tail(&action_list, &act->alist);
        }
    }
}
Exemplo n.º 4
0
static int do_command(char *str)
{
	int action, id;
	char action_str[10+1] = {0}, id_str[64+1] = {0};

	if (0 == strncasecmp(str, "HELP", strlen(str))) {
		print_help(stdout);
		return 0;
	}

	if (2 != sscanf(str, " %10s %64s", action_str, id_str))
		return -1;

	if (0 == strncasecmp(action_str, "TARGET", strlen(action_str)))
		return parse_target(id_str);

	action = parse_action(action_str);
	id = parse_id(id_str);

	if (action == BAD_ACTION || id == BAD_ID)
		return -1;

	if (id == AMBIGUOUS_ID) {
		fprintf(stdout, "id %s is too ambiguous\n", id_str);
		return 0;
	}

	fprintf(stdout, "sending: %s %s\n",
		action_string[action], idtab[id].name);

	idtab[id].func(action, id, str);

	return 0;
}
Exemplo n.º 5
0
int
read_options(struct client_options *cl_opts, int argc, char **argv) {

  const char *options = "u:p:h:c:o:A:N:f:s:";
  char *action = NULL;
  char cur_option;
  memset(cl_opts, 0, sizeof(struct client_options));

  while ((cur_option = (char)getopt(argc, argv, options)) != -1) {
    if (!optarg) {
      usage();
      return 0;
    }
    switch(cur_option) {
      case 's':
        cl_opts->str_filesize = optarg;
        break;
      case 'u':
        cl_opts->username = optarg; 
        break;   
      case 'p':
        cl_opts->password = optarg;
        break;
      case 'h':
        cl_opts->url = optarg;
        break;
      case 'c':
        cl_opts->container = optarg;
        break;
      case 'o':
        cl_opts->object = optarg;
        break;
      case 'A':
        action = optarg;
        break;
      case 'N':
        cl_opts->path = optarg;
        break;
      case 'f':
        cl_opts->filename = optarg;
        break;
      case '?':
      default:
        usage();
        return 0;
        break;
    }
  }
  if ((action == NULL) && (cl_opts->path == NULL)) {
    usage();
    return 0;
  }
  if (action != NULL) {
    cl_opts->action = parse_action(action);
  } else {
    cl_opts->action = ACTION_NODELIST;
  }
  
}
Exemplo n.º 6
0
static int cgroup_parse_opt(struct filter_util *qu, char *handle,
			   int argc, char **argv, struct nlmsghdr *n)
{
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	long h = 0;

	if (handle) {
		h = strtol(handle, NULL, 0);
		if (h == LONG_MIN || h == LONG_MAX) {
			fprintf(stderr, "Illegal handle \"%s\", must be numeric.\n",
			    handle);
			return -1;
		}
	}

	t->tcm_handle = h;

	tail = (struct rtattr*)(((void*)n)+NLMSG_ALIGN(n->nlmsg_len));
	addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "match") == 0) {
			NEXT_ARG();
			if (parse_ematch(&argc, &argv, TCA_CGROUP_EMATCHES, n)) {
				fprintf(stderr, "Illegal \"ematch\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "action") == 0) {
			NEXT_ARG();
			if (parse_action(&argc, &argv, TCA_CGROUP_ACT, n)) {
				fprintf(stderr, "Illegal \"action\"\n");
				return -1;
			}
			continue;

		} else if (matches(*argv, "police") == 0) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_CGROUP_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		} else if (strcmp(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argc--; argv++;
	}

	tail->rta_len = (((void*)n)+n->nlmsg_len) - (void*)tail;
	return 0;
}
Exemplo n.º 7
0
void
SpriteData::parse(const Pathname& dir, FileReader& reader)
{
  std::vector<FileReader> sections = reader.get_sections();
  for(std::vector<FileReader>::iterator i = sections.begin(); i != sections.end(); ++i)
    actions.push_back(parse_action(dir, *i));
  
  if(actions.size() == 0)
    throw std::runtime_error("Sprite contains no actions");
}
Exemplo n.º 8
0
/*
=================
G_AddIP_f
=================
*/
void G_AddIP_f(edict_t *ent)
{
    unsigned mask, compare;
    unsigned duration;
    ipaction_t action;
    int start, argc;
    char *s;

    start = ent ? 0 : 1;
    argc = gi.argc() - start;

    if (argc < 2) {
        gi.cprintf(ent, PRINT_HIGH, "Usage: %s <ip-mask> [duration] [action]\n", gi.argv(start));
        return;
    }

    if (numipfilters == MAX_IPFILTERS) {
        gi.cprintf(ent, PRINT_HIGH, "IP filter list is full\n");
        return;
    }

    s = gi.argv(start + 1);
    if (!parse_filter(s, &mask, &compare)) {
        gi.cprintf(ent, PRINT_HIGH, "Bad filter address: %s\n", s);
        return;
    }

    duration = ent ? DEF_DURATION : 0;
    action = IPA_BAN;
    if (argc > 2) {
        s = gi.argv(start + 2);
        duration = parse_duration(s);
        if (ent) {
            if (!duration) {
                gi.cprintf(ent, PRINT_HIGH, "You may not add permanent bans.\n");
                return;
            }
            if (duration > MAX_DURATION) {
                duration = MAX_DURATION;
            }
        }
        if (argc > 3) {
            s = gi.argv(start + 3);
            action = parse_action(s);
            if (action == IPA_NONE) {
                gi.cprintf(ent, PRINT_HIGH, "Bad action specifier: %s\n", s);
                return;
            }
        }
    }

    add_filter(action, mask, compare, duration, ent);
}
Exemplo n.º 9
0
SpriteData::SpriteData(const lisp::Lisp* lisp, const std::string& basedir)
{
  lisp::ListIterator iter(lisp);
  while(iter.next()) {
    if(iter.item() == "name") {
      iter.value()->get(name);
    } else if(iter.item() == "action") {
      parse_action(iter.lisp(), basedir);
    } else {
      log_warning << "Unknown sprite field: " << iter.item() << std::endl;
    }
  }
  if(actions.empty())
    throw std::runtime_error("Error: Sprite wihtout actions.");
}
Exemplo n.º 10
0
SpriteData::SpriteData(const ReaderMapping& lisp, const std::string& basedir) :
  actions(),
  name()
{
  auto iter = lisp.get_iter();
  while(iter.next()) {
    if(iter.get_key() == "name") {
      iter.get(name);
    } else if(iter.get_key() == "action") {
      parse_action(iter.as_mapping(), basedir);
    } else {
      log_warning << "Unknown sprite field: " << iter.get_key() << std::endl;
    }
  }
  if(actions.empty())
    throw std::runtime_error("Error: Sprite without actions.");
}
Exemplo n.º 11
0
static void
parse_actions(struct action_context *ctx)
{
    /* "drop;" by itself is a valid (empty) set of actions, but it can't be
     * combined with other actions because that doesn't make sense. */
    if (ctx->lexer->token.type == LEX_T_ID
        && !strcmp(ctx->lexer->token.s, "drop")
        && lexer_lookahead(ctx->lexer) == LEX_T_SEMICOLON) {
        lexer_get(ctx->lexer);  /* Skip "drop". */
        lexer_get(ctx->lexer);  /* Skip ";". */
        if (ctx->lexer->token.type != LEX_T_END) {
            action_syntax_error(ctx, "expecting end of input");
        }
        return;
    }

    while (ctx->lexer->token.type != LEX_T_END) {
        if (!parse_action(ctx)) {
            return;
        }
    }
}
Exemplo n.º 12
0
int tc_action_modify(int cmd, unsigned flags, int *argc_p, char ***argv_p)
{
	int argc = *argc_p;
	char **argv = *argv_p;
	int ret = 0;

	struct rtattr *tail;
	struct {
		struct nlmsghdr         n;
		struct tcamsg           t;
		char                    buf[MAX_MSG];
	} req;

	req.t.tca_family = AF_UNSPEC;

	memset(&req, 0, sizeof(req));

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcamsg));
	req.n.nlmsg_flags = NLM_F_REQUEST|flags;
	req.n.nlmsg_type = cmd;
	tail = NLMSG_TAIL(&req.n);
	argc -=1;
	argv +=1;
	if (parse_action(&argc, &argv, TCA_ACT_TAB, &req.n)) {
		fprintf(stderr, "Illegal \"action\"\n");
		return -1;
	}
	tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail;

	if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) {
		fprintf(stderr, "We have an error talking to the kernel\n");
		ret = -1;
	}

	*argc_p = argc;
	*argv_p = argv;

	return ret;
}
Exemplo n.º 13
0
Arquivo: f_fw.c Projeto: NieHao/R7000
static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
	struct tc_police tp;
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;

	memset(&tp, 0, sizeof(tp));

	if (handle) {
		if (get_u32(&t->tcm_handle, handle, 0)) {
			fprintf(stderr, "Illegal \"handle\"\n");
			return -1;
		}
	}

	if (argc == 0)
		return 0;

	tail = NLMSG_TAIL(n);
	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "classid") == 0 ||
		    matches(*argv, "flowid") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_FW_CLASSID, &handle, 4);
		} else if (matches(*argv, "police") == 0) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_FW_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "action") == 0) {
			NEXT_ARG();
			if (parse_action(&argc, &argv, TCA_FW_ACT, n)) {
				fprintf(stderr, "Illegal fw \"action\"\n");
				return -1;
			}
			continue;
		} else if (strcmp(*argv, "indev") == 0) {
			char d[IFNAMSIZ+1];
			memset(d, 0, sizeof (d));
			argc--;
			argv++;
			if (argc < 1) {
				fprintf(stderr, "Illegal indev\n");
				return -1;
			}
			strncpy(d, *argv, sizeof (d) - 1);
			addattr_l(n, MAX_MSG, TCA_FW_INDEV, d, strlen(d) + 1);
		} else if (strcmp(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argc--; argv++;
	}
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
Exemplo n.º 14
0
static
#endif
int real_main(int argc, char *argv[])
{
	int ret=1;
	int option=0;
	int daemon=1;
	int forking=1;
	int strip=0;
	int randomise=0;
	struct lock *lock=NULL;
	struct conf **confs=NULL;
	int forceoverwrite=0;
	enum action act=ACTION_LIST;
	const char *backup=NULL;
	const char *backup2=NULL;
	char *restoreprefix=NULL;
	char *stripfrompath=NULL;
	const char *regex=NULL;
	const char *browsefile=NULL;
	char *browsedir=NULL;
	const char *conffile=get_conf_path();
	const char *orig_client=NULL;
	const char *logfile=NULL;
	// The orig_client is the original client that the normal client
	// would like to restore from.
#ifndef HAVE_WIN32
	int generate_ca_only=0;
#endif
	int vss_restore=1;
	int test_confs=0;
	enum burp_mode mode;

	log_init(argv[0]);
#ifndef HAVE_WIN32
	if(!strcmp(prog, "bedup"))
		return run_bedup(argc, argv);
	if(!strcmp(prog, "bsigs"))
		return run_bsigs(argc, argv);
#endif

	while((option=getopt(argc, argv, "a:b:c:C:d:fFghil:nq:Qr:s:tvxjz:?"))!=-1)
	{
		switch(option)
		{
			case 'a':
				if(parse_action(&act, optarg)) goto end;
				break;
			case 'b':
				// The diff command may have two backups
				// specified.
				if(!backup2 && backup) backup2=optarg;
				if(!backup) backup=optarg;
				break;
			case 'c':
				conffile=optarg;
				break;
			case 'C':
				orig_client=optarg;
				break;
			case 'd':
				restoreprefix=optarg; // for restores
				browsedir=optarg; // for lists
				break;
			case 'f':
				forceoverwrite=1;
				break;
			case 'F':
				daemon=0;
				break;
			case 'g':
#ifndef HAVE_WIN32
				generate_ca_only=1;
#endif
				break;
			case 'i':
				cmd_print_all();
				ret=0;
				goto end;
			case 'l':
				logfile=optarg;
				break;
			case 'n':
				forking=0;
				break;
			case 'q':
				randomise=atoi(optarg);
				break;
			case 'Q':
				log_force_quiet();
				break;
			case 'r':
				regex=optarg;
				break;
			case 's':
				strip=atoi(optarg);
				break;
			case 'v':
				printf("%s-%s\n", progname(), VERSION);
				ret=0;
				goto end;
			case 'x':
				vss_restore=0;
				break;
			case 't':
				test_confs=1;
				break;
			case 'z':
				browsefile=optarg;
				break;
			case 'h':
			case '?':
			default:
				usage();
				goto end;
		}
	}
	if(optind<argc)
	{
		usage();
		goto end;
	}

	if(act==ACTION_MONITOR)
	{
		// Try to output everything in JSON.
		log_set_json(1);
#ifndef HAVE_WIN32
		// Need to do this so that processes reading stdout get the
		// result of the printfs of logp straight away.
		setlinebuf(stdout);
#endif
	}

	if(!(confs=confs_alloc()))
		goto end;

	if(reload(confs, conffile, 1))
		goto end;

	// Dry run to test config file syntax.
	if(test_confs)
	{
		ret=run_test_confs(confs, orig_client);
		goto end;
	}

	if(!backup) switch(act)
	{
		case ACTION_DELETE:
			logp("No backup specified for deletion.\n");
			goto end;
		case ACTION_RESTORE:
		case ACTION_VERIFY:
		case ACTION_DIFF:
		case ACTION_DIFF_LONG:
			logp("No backup specified. Using the most recent.\n");
			backup="0";
		default:
			break;
	}
	if(!backup2) switch(act)
	{
		case ACTION_DIFF:
		case ACTION_DIFF_LONG:
			logp("No second backup specified. Using file system scan.\n");
			backup2="n"; // For 'next'.
		default:
			break;
	}

	// The logfile option is only used for the status client stuff.
	if(logfile
	  && (act!=ACTION_STATUS
		&& act!=ACTION_STATUS_SNAPSHOT))
			logp("-l <logfile> option obsoleted\n");

	if(orig_client
	  && *orig_client
	  && set_string(confs[OPT_ORIG_CLIENT], orig_client))
		goto end;

	// The random delay needs to happen before the lock is got, otherwise
	// you would never be able to use burp by hand.
	if(randomise) set_int(confs[OPT_RANDOMISE], randomise);
	mode=get_e_burp_mode(confs[OPT_BURP_MODE]);
	if(mode==BURP_MODE_CLIENT
	  && (act==ACTION_BACKUP_TIMED || act==ACTION_TIMER_CHECK))
		random_delay(confs);

	if(mode==BURP_MODE_SERVER
	  && act==ACTION_CHAMP_CHOOSER)
	{
		// These server modes need to run without getting the lock.
	}
	else if(mode==BURP_MODE_CLIENT
	  && (act==ACTION_LIST
		|| act==ACTION_LIST_LONG
		|| act==ACTION_DIFF
		|| act==ACTION_DIFF_LONG
		|| act==ACTION_STATUS
		|| act==ACTION_STATUS_SNAPSHOT
		|| act==ACTION_MONITOR))
	{
		// These client modes need to run without getting the lock.
	}
	else
	{
		const char *lockfile=confs_get_lockfile(confs);
		if(!(lock=lock_alloc_and_init(lockfile)))
			goto end;
		lock_get(lock);
		switch(lock->status)
		{
			case GET_LOCK_GOT: break;
			case GET_LOCK_NOT_GOT:
				logp("Could not get lockfile.\n");
				logp("Another process is probably running,\n");
				goto end;
			case GET_LOCK_ERROR:
			default:
				logp("Could not get lockfile.\n");
				logp("Maybe you do not have permissions to write to %s.\n", lockfile);
				goto end;
		}
	}

	set_int(confs[OPT_OVERWRITE], forceoverwrite);
	set_int(confs[OPT_STRIP], strip);
	set_int(confs[OPT_FORK], forking);
	set_int(confs[OPT_DAEMON], daemon);

	strip_trailing_slashes(&restoreprefix);
	strip_trailing_slashes(&browsedir);
	if(replace_conf_str(confs[OPT_BACKUP], backup)
	  || replace_conf_str(confs[OPT_BACKUP2], backup2)
	  || replace_conf_str(confs[OPT_RESTOREPREFIX], restoreprefix)
	  || replace_conf_str(confs[OPT_STRIP_FROM_PATH], stripfrompath)
	  || replace_conf_str(confs[OPT_REGEX], regex)
	  || replace_conf_str(confs[OPT_BROWSEFILE], browsefile)
	  || replace_conf_str(confs[OPT_BROWSEDIR], browsedir)
	  || replace_conf_str(confs[OPT_MONITOR_LOGFILE], logfile))
		goto end;

	base64_init();
	hexmap_init();

	if(mode==BURP_MODE_SERVER)
	{
#ifdef HAVE_WIN32
		logp("Sorry, server mode is not implemented for Windows.\n");
#else
		ret=server_modes(act,
			conffile, lock, generate_ca_only, confs);
#endif
	}
	else
	{
		ret=client(confs, act, vss_restore);
	}

end:
	lock_release(lock);
	lock_free(&lock);
	confs_free(&confs);
	return ret;
}
Exemplo n.º 15
0
int main(int argc, char *argv[])
{
	struct opal_prd_ctx _ctx;
	enum action action;
	int rc;

	check_abi();

	ctx = &_ctx;
	memset(ctx, 0, sizeof(*ctx));
	ctx->vlog = pr_log_stdio;
	ctx->use_syslog = true;

	/* Parse options */
	for (;;) {
		int c;

		c = getopt_long(argc, argv, "f:p:dhse", opal_diag_options, NULL);
		if (c == -1)
			break;

		switch (c) {
		case 'f':
			ctx->hbrt_file_name = optarg;
			break;
		case 'd':
			ctx->debug = true;
			break;
		case 'p':
			ctx->pnor.path = strndup(optarg, PATH_MAX);
			break;
		case 's':
			ctx->use_syslog = false;
			break;
		case 'h':
			usage(argv[0]);
			return EXIT_SUCCESS;
		case 'e':
			ctx->expert_mode = true;
			break;
		case 'v':
			print_version();
			return EXIT_SUCCESS;
		case '?':
		default:
			usage(argv[0]);
			return EXIT_FAILURE;
		}
	}

	if (optind < argc) {
		rc = parse_action(argv[optind], &action);
		if (rc)
			return EXIT_FAILURE;
	} else {
		action = ACTION_RUN_DAEMON;
	}

	if (is_prd_supported() < 0) {
		pr_log(LOG_ERR, "CTRL: PowerNV OPAL runtime diagnostic "
				"is not supported on this system");
		return -1;
	}

	switch (action) {
	case ACTION_RUN_DAEMON:
		rc = run_prd_daemon(ctx);
		break;
	case ACTION_OCC_CONTROL:
		if (optind + 1 >= argc) {
			pr_log(LOG_ERR, "CTRL: occ command requires "
					"an argument");
			return EXIT_FAILURE;
		}

		rc = send_occ_control(ctx, argv[optind + 1]);
		break;
	case ACTION_ATTR_OVERRIDE:
		if (optind + 1 >= argc) {
			pr_log(LOG_ERR, "CTRL: attribute override command "
					"requires an argument");
			return EXIT_FAILURE;
		}

		rc = send_attr_override(ctx, argc - optind - 1, &argv[optind + 1]);
		break;
	case ACTION_HTMGT_PASSTHRU:
		if (optind + 1 >= argc) {
			pr_log(LOG_ERR, "CTRL: htmgt passthru requires at least "
					"one argument");
			return EXIT_FAILURE;
		}

		rc = send_htmgt_passthru(ctx, argc - optind - 1,
					 &argv[optind + 1]);
		break;
	case ACTION_RUN_COMMAND:
		if (optind + 1 >= argc) {
			pr_log(LOG_ERR, "CTRL: run command requires "
					"argument(s)");
			return EXIT_FAILURE;
		}

		rc = send_run_command(ctx, argc - optind - 1, &argv[optind + 1]);
		break;
	default:
		break;
	}

	return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
Exemplo n.º 16
0
/* This is to be called at every loop() */
int ReceiverRouter::get_stm_action() {
    read_channels(); //Once every 500ms
    return parse_action();
}
Exemplo n.º 17
0
Arquivo: prog.c Projeto: jkniiv/burp
int main (int argc, char *argv[])
{
    int ret=1;
    int option=0;
    int daemon=1;
    int forking=1;
    int strip=0;
    struct lock *lock=NULL;
    struct conf *conf=NULL;
    int forceoverwrite=0;
    enum action act=ACTION_LIST;
    const char *backup=NULL;
    const char *restoreprefix=NULL;
    const char *regex=NULL;
    const char *browsefile=NULL;
    const char *browsedir=NULL;
    const char *conffile=get_conf_path();
    const char *orig_client=NULL;
    // The orig_client is the original client that the normal client
    // would like to restore from.
#ifndef HAVE_WIN32
    const char *sclient=NULL; // Status monitor client to view.
    int generate_ca_only=0;
#endif
    int vss_restore=1;
    int json=0;

    init_log(argv[0]);

    while((option=getopt(argc, argv, "a:b:c:C:d:ghfFil:nr:s:vxjz:?"))!=-1)
    {
        switch(option)
        {
        case 'a':
            if(parse_action(&act, optarg)) goto end;
            break;
        case 'b':
            backup=optarg;
            break;
        case 'c':
            conffile=optarg;
            break;
        case 'C':
            orig_client=optarg;
#ifndef HAVE_WIN32
            sclient=optarg;
#endif
            break;
        case 'd':
            restoreprefix=optarg; // for restores
            browsedir=optarg; // for lists
            break;
        case 'f':
            forceoverwrite=1;
            break;
        case 'F':
            daemon=0;
            break;
        case 'g':
#ifndef HAVE_WIN32
            generate_ca_only=1;
#endif
            break;
        case 'i':
            cmd_print_all();
            ret=0;
            goto end;
        case 'l':
            logp("-l <logfile> option obsoleted\n");
            break;
        case 'n':
            forking=0;
            break;
        case 'r':
            regex=optarg;
            break;
        case 's':
            strip=atoi(optarg);
            break;
        case 'v':
            printf("%s-%s\n", progname(), VERSION);
            ret=0;
            goto end;
        case 'x':
            vss_restore=0;
            break;
        case 'j':
            json=1;
            break;
        case 'z':
            browsefile=optarg;
            break;
        case 'h':
        case '?':
        default:
            usage();
            goto end;
        }
    }
    if(optind<argc)
    {
        usage();
        goto end;
    }

    if(!(conf=conf_alloc()))
        goto end;

    if(reload(conf, conffile,
              1 /* first time */,
              0 /* no oldmax_children setting */,
              0 /* no oldmax_status_children setting */,
              json)) goto end;

    if((act==ACTION_RESTORE || act==ACTION_VERIFY) && !backup)
    {
        logp("No backup specified. Using the most recent.\n");
        backup="0";
    }

    if(act==ACTION_DELETE && !backup)
    {
        logp("No backup specified for deletion.\n");
        goto end;
    }

    if(conf->mode==MODE_CLIENT)
    {
        if(orig_client && *orig_client)
        {
            if(!(conf->orig_client=strdup(orig_client)))
            {
                log_out_of_memory(__func__);
                goto end;
            }
        }
    }

    if(conf->mode==MODE_SERVER
            && (act==ACTION_STATUS
                || act==ACTION_STATUS_SNAPSHOT
                || act==ACTION_CHAMP_CHOOSER))
    {
        // These server modes need to run without getting the lock.
    }
    else
    {
        if(!(lock=lock_alloc_and_init(conf->lockfile)))
            goto end;
        lock_get(lock);
        switch(lock->status)
        {
        case GET_LOCK_GOT:
            break;
        case GET_LOCK_NOT_GOT:
            logp("Could not get lockfile.\n");
            logp("Another process is probably running,\n");
            goto end;
        case GET_LOCK_ERROR:
        default:
            logp("Could not get lockfile.\n");
            logp("Maybe you do not have permissions to write to %s.\n", conf->lockfile);
            goto end;
        }
    }

    conf->overwrite=forceoverwrite;
    conf->strip=strip;
    conf->forking=forking;
    conf->daemon=daemon;
    if(replace_conf_str(backup, &conf->backup)
            || replace_conf_str(restoreprefix, &conf->restoreprefix)
            || replace_conf_str(regex, &conf->regex)
            || replace_conf_str(browsefile, &conf->browsefile)
            || replace_conf_str(browsedir, &conf->browsedir))
        goto end;
    if(conf->mode==MODE_SERVER)
    {
#ifdef HAVE_WIN32
        logp("Sorry, server mode is not implemented for Windows.\n");
#else
        if(act==ACTION_STATUS || act==ACTION_STATUS_SNAPSHOT)
        {
            // We are running on the server machine, being a client
            // of the burp server, getting status information.
            ret=status_client_ncurses(conf, act, sclient);
        }
        else if(act==ACTION_CHAMP_CHOOSER)
        {
            // We are running on the server machine, wanting to
            // be a standalone champion chooser process.
            if(!sclient || !*sclient)
            {
                logp("No client name specified for standalone champion chooser process.\n");
                logp("Try using the '-C' option.\n");
                ret=1;
            }
            else
                ret=champ_chooser_server_standalone(conf,
                                                    sclient);
        }
        else
            ret=server(conf, conffile, lock, generate_ca_only);
#endif
    }
    else
    {
        logp("before client\n");
        ret=client(conf, act, vss_restore, json);
        logp("after client\n");
    }

end:
    lock_release(lock);
    lock_free(&lock);
    conf_free(conf);
    return ret;
}
Exemplo n.º 18
0
/*
 Add user input to the 'current' string (as defined by d->str).
 */
void string_add(Descriptor *d, char *str)
{
	FILE *fl;
	int terminator = 0, action = 0;
	register int i = 2, j = 0;
	char actions[MAX_INPUT_LENGTH];


	/* determine if this is the terminal string, and truncate if so */
	/* changed to only accept '@' at the beginning of line - J. Elson 1/17/94 */
	/* Changed to accept '/<letter>' style editing commands - instead */
	/*   of solitary '@' to end. - M. Scott 10/15/96 */

	delete_doubledollar(str);

	if ((action = ((*str == '/') && (str[1] != '/') && (str[1] != '*'))))
	{
		while (str[i] != '\0')
		{
			actions[j] = str[i];
			++i;
			++j;
		}
		actions[j] = '\0';
		*str = '\0';

		switch (str[1])
		{
			case 'a':
				terminator = 2;		/* Working on an abort message, */
				break;
			case 'c':
				if (*(d->str))
				{
					delete [](*(d->str));
					*(d->str) = NULL;
					d->send("Current buffer cleared.\r\n");
				}
				else
					d->send("Current buffer empty.\r\n");
				break;
			case 'd':
				parse_action(PARSE_DELETE, actions, d);
				break;
			case 'e':
				parse_action(PARSE_EDIT, actions, d);
				break;
			case 'f':
				if (*(d->str))
					parse_action(PARSE_FORMAT, actions, d);
				else
					d->send("Current buffer empty.\r\n");
				break;
			case 'i':
				if (*(d->str))
					parse_action(PARSE_INSERT, actions, d);
				else
					d->send("Current buffer empty.\r\n");
				break;
			case 'h':
				parse_action(PARSE_HELP, actions, d);
				break;
			case 'l':
				if (*d->str)
					parse_action(PARSE_LIST_NORM, actions, d);
				else
					d->send("Current buffer empty.\r\n");
				break;
			case 'n':
				if (*d->str)
					parse_action(PARSE_LIST_NUM, actions, d);
				else
					d->send("Current buffer empty.\r\n");
				break;
			case 'r':
				parse_action(PARSE_REPLACE, actions, d);
				break;
			case 's':
				terminator = 1;
				*str = '\0';
				break;
			default:
				d->send("Invalid option.\r\n");
				break;
		}
		
		if(!terminator)
			return;
	}


	if(!terminator)
	{
		if (!(*d->str))
		{
			if (strlen(str) > d->max_str)
			{
				d->send("String too long - Truncated.\r\n");
				*(str + d->max_str) = '\0';
				/* Changed this to NOT abort out.. just give warning. */
				/* terminator = 1; */
			}
			(*d->str) = new char[d->max_str];
			*(*d->str) = '\0';
			d->addToString(str);
		}
		else
		{
			if (!d->addToString(str))
				d->send("String too long, limit reached on message. Last line ignored.\r\n");
		}
	}
	
	if(terminator)
	{
		/*
		 * OLC Edits
		 */
		extern void oedit_disp_menu(Descriptor *d);
		extern void oedit_disp_extradesc_menu(Descriptor *d);
		extern void redit_disp_menu(Descriptor *d);
		extern void redit_disp_extradesc_menu(Descriptor *d);
		extern void redit_disp_exit_menu(Descriptor *d);
		extern void medit_disp_menu(Descriptor *d);
		extern void CeditGameOptionsMenu(Descriptor *d);
		extern void cedit_disp_operation_options(Descriptor *d);

#if defined(OASIS_MPROG)

		extern void medit_change_mprog(Descriptor *d);

		if (STATE(d) == CON_MEDIT)
		{
			switch (OLC_MODE(d))
			{
				case MEDIT_D_DESC:
					medit_disp_menu(d);
					break;
				case MEDIT_MPROG_COMLIST:
					medit_change_mprog(d);
					break;
			}
		}
#endif

		/*
		 * Here we check for the abort option and reset the pointers.
		 */
		if ((terminator == 2) &&
			((STATE(d) == CON_REDIT) ||
			(STATE(d) == CON_MEDIT) ||
			(STATE(d) == CON_OEDIT) ||
			(STATE(d) == CON_EXDESC) ||
			STATE(d) == CON_CEDIT))
		{
			delete[] (*d->str);
			if (d->backstr)
			{
				*d->str = d->backstr;
			}
			else
				*d->str = NULL;

			d->backstr = NULL;
			d->str = NULL;
		}
		/*
		 * This fix causes the editor to NULL out empty messages -- M. Scott
		 * Fixed to fix the fix for empty fixed messages. -- gg
		 */
		if ((d->str) && (*d->str) && (**d->str == '\0'))
		{
			delete[] (*d->str);
			if(!d->character  || d->str != &d->character->player.description)
				*d->str = str_dup("Nothing.\r\n");
			else
				*d->str = str_dup(" ");
		}
		if (STATE(d) == CON_MEDIT)
			medit_disp_menu(d);
		if (STATE(d) == CON_OEDIT)
		{
			switch (OLC_MODE(d))
			{
				case OEDIT_ACTDESC:
					oedit_disp_menu(d);
					break;
				case OEDIT_EXTRADESC_DESCRIPTION:
					oedit_disp_extradesc_menu(d);
					break;
			}
		}
		else if (STATE(d) == CON_REDIT)
		{
			switch (OLC_MODE(d))
			{
				case REDIT_DESC:
					redit_disp_menu(d);
					break;
				case REDIT_EXIT_DESCRIPTION:
					redit_disp_exit_menu(d);
					break;
				case REDIT_EXTRADESC_DESCRIPTION:
					redit_disp_extradesc_menu(d);
					break;
			}
		}
		else if(STATE(d) == CON_CEDIT)
		{
			switch(OLC_MODE(d))
			{
				case CEDIT_GAME_OPTIONS_MENU:
					CeditGameOptionsMenu(d);
					break;
				case CEDIT_OPERATION_OPTIONS_MENU:
					CeditGameOptionsMenu(d);
					break;
			}
		}
		else if (!d->connected && d->character && !IS_NPC(d->character))
		{
			if (terminator == 1)
			{
				if (*d->str && strlen(*d->str) == 0)
				{
					delete (*d->str);
					*d->str = NULL;
				}
			}
			else
			{
				delete (*d->str);
				if (d->backstr)
					*d->str = d->backstr;
				else
					*d->str = NULL;
				d->backstr = NULL;
				d->sendRaw("Message aborted.\r\n");
			}
		}
		if (d->character && !IS_NPC(d->character))
		{
			REMOVE_BIT(PLR_FLAGS(d->character), Q_BIT(PLR_WRITING));
			REMOVE_BIT(PLR_FLAGS(d->character), Q_BIT(PLR_MAILING));
		}

		if (d->backstr)
			delete [](d->backstr);

		d->backstr = NULL;
		d->str = NULL;
	}

	//Add a newline only if able -Galnor, 03/20/2009
	else if (!action)
		d->addToString("\r\n");
}
Exemplo n.º 19
0
int
main(int argc, char* argv[])
{
   try
   {
      auto act = parse_action(argc, argv);
      switch (act)
      {
         case action::WATCH:
         {
            auto vars = parse_variable_ids(argc, argv);
            fv::var_observer obs(vars);
            auto disconnection = obs.disconnection();
            disconnection.get();
            return 0;
         }
         case action::SET:
         {
            auto var_id = fv::variable_id::parse(argv[2]);
            auto var_value = parse_variable_value(argv[3]);
            fv::var_observer obs(var_id);
            std::cerr <<
                  oac::format(
                        "Setting %s with value %s",
                        var_id.to_string(),
                        var_value.to_string()) <<
                  std::endl;
            obs.set_value(var_id, var_value);
            std::cerr << "Value set successfully" << std::endl;
            return 0;
            break;
         }
      }
   }
   catch (const fv::variable_id::parse_error& e)
   {
      std::cerr <<
            "Error while parsing program arguments: " <<
            e.message() <<
            std::endl;
   }
   catch (const fv::client::communication_error& comm_error)
   {
      std::cerr << "Communication error: " << std::endl;
      std::cerr << comm_error.report() << std::endl << std::endl;
   }
   catch (const oac::exception& e)
   {
      std::cerr << "Unexpected exception thrown" << std::endl;
      std::cerr << e.report() << std::endl << std::endl;
   }
   catch (...)
   {
      std::cerr <<
            "Unexpected exception thrown: no further details available" <<
            std::endl;
   }

   print_help();
   return 1;
}
Exemplo n.º 20
0
int main(int argc, char *argv[])
{
	struct opal_prd_ctx _ctx;
	enum action action;
	int rc;

	ctx = &_ctx;
	memset(ctx, 0, sizeof(*ctx));
	ctx->vlog = pr_log_stdio;
	ctx->use_syslog = true;

	/* Parse options */
	for (;;) {
		int c;

		c = getopt_long(argc, argv, "f:p:dhs", opal_diag_options, NULL);
		if (c == -1)
			break;

		switch (c) {
		case 'f':
			ctx->hbrt_file_name = optarg;
			break;
		case 'd':
			ctx->debug = true;
			break;
		case 'p':
			ctx->pnor.path = strndup(optarg, PATH_MAX);
			break;
		case 's':
			ctx->use_syslog = false;
			break;
		case 'h':
			usage(argv[0]);
			return EXIT_SUCCESS;
		case 'v':
			print_version();
			return EXIT_SUCCESS;
		case '?':
		default:
			usage(argv[0]);
			return EXIT_FAILURE;
		}
	}

	if (optind < argc) {
		rc = parse_action(argv[optind], &action);
		if (rc)
			return EXIT_FAILURE;
	} else {
		action = ACTION_RUN_DAEMON;
	}

	if (action == ACTION_RUN_DAEMON) {
		rc = run_prd_daemon(ctx);

	} else if (action == ACTION_OCC_CONTROL) {

		if (optind + 1 >= argc) {
			pr_log(LOG_ERR, "CTRL: occ command requires "
					"an argument");
			return EXIT_FAILURE;
		}

		rc = send_occ_control(ctx, argv[optind + 1]);
	}

	return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
Exemplo n.º 21
0
int init_actions(struct optstruct *opts) {
    const struct optstruct *opt;

    if(!(opt = optget(opts, "LogInfected"))->enabled || !strcasecmp(opt->strarg, "Off"))
	loginfected = LOGINF_NONE;
    else if(!strcasecmp(opt->strarg, "Basic"))
	loginfected = LOGINF_BASIC;
    else if(!strcasecmp(opt->strarg, "Full"))
	loginfected = LOGINF_FULL;
    else {
	logg("!Invalid setting %s for option LogInfected\n", opt->strarg);
	return 1;
    }

    if((opt = optget(opts, "LogClean"))->enabled) {
	if(!strcasecmp(opt->strarg, "Basic"))
	    loginfected |= LOGCLN_BASIC;
	else if(!strcasecmp(opt->strarg, "Full"))
	    loginfected |= LOGCLN_FULL;
	else if(strcasecmp(opt->strarg, "Off")) {
	    logg("!Invalid setting %s for option LogClean\n", opt->strarg);
	    return 1;
	}
    }

    if((opt = optget(opts, "VirusAction"))->enabled)
	viraction = strdup(opt->strarg);

    if((opt = optget(opts, "OnFail"))->enabled) {
	switch(parse_action(opt->strarg)) {
	case 0:
	    FailAction = SMFIS_ACCEPT;
	    break;
	case 1:
	    FailAction = SMFIS_TEMPFAIL;
	    break;
	case 2:
	    FailAction = SMFIS_REJECT;
	    break;
	default:
	    logg("!Invalid action %s for option OnFail\n", opt->strarg);
	    return 1;
	}
    } else FailAction = SMFIS_TEMPFAIL;

    if((opt = optget(opts, "OnClean"))->enabled) {
	switch(parse_action(opt->strarg)) {
	case 0:
	    CleanAction = action_accept;
	    break;
	case 1:
	    CleanAction = action_defer;
	    break;
	case 2:
	    CleanAction = action_reject;
	    break;
	case 3:
	    CleanAction = action_blackhole;
	    break;
	case 4:
	    CleanAction = action_quarantine;
	    break;
	default:
	    logg("!Invalid action %s for option OnClean\n", opt->strarg);
	    return 1;
	}
    } else CleanAction = action_accept;

    if((opt = optget(opts, "OnInfected"))->enabled) {
	switch(parse_action(opt->strarg)) {
	case 0:
	    InfectedAction = action_accept;
	    break;
	case 1:
	    InfectedAction = action_defer;
	    break;
	case 3:
	    InfectedAction = action_blackhole;
	    break;
	case 4:
	    InfectedAction = action_quarantine;
	    break;
	case 2:
	    InfectedAction = action_reject_msg;
	    if((opt = optget(opts, "RejectMsg"))->enabled) {
		const char *src = opt->strarg;
		char *dst, c;
		int gotpctv = 0;

		rejectfmt = dst = malloc(strlen(src) * 4 + 1);
		if(!dst) {
		    logg("!Failed to allocate memory for RejectMsg\n");
		    return 1;
		}
		while ((c = *src++)) {
		    if(!isprint(c)) {
			logg("!RejectMsg contains non printable characters\n");
			free(rejectfmt);
			return 1;
		    }
		    *dst++ = c;
		    if(c == '%') {
			if(*src == 'v') {
			    if(gotpctv) {
				logg("!%%v may appear at most once in RejectMsg\n");
				free(rejectfmt);
				return 1;
			    }
			    gotpctv |= 1;
			    src++;
			    *dst++ = 's';
			} else {
			    dst[0] = dst[1] = dst[2] = '%';
			    dst += 3;
			}
		    }
		}
		*dst = '\0';
	    }
	    break;
	default:
	    logg("!Invalid action %s for option OnInfected\n", opt->strarg);
	    return 1;
	}
    } else InfectedAction = action_quarantine;
    return 0;
}
Exemplo n.º 22
0
static int flow_parse_opt(struct filter_util *fu, char *handle,
			  int argc, char **argv, struct nlmsghdr *n)
{
	struct tc_police tp;
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	__u32 mask = ~0U, xor = 0;
	__u32 keys = 0, nkeys = 0;
	__u32 mode = FLOW_MODE_MAP;
	__u32 tmp;

	memset(&tp, 0, sizeof(tp));

	if (handle) {
		if (get_u32(&t->tcm_handle, handle, 0)) {
			fprintf(stderr, "Illegal \"handle\"\n");
			return -1;
		}
	}

	tail = NLMSG_TAIL(n);
	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "map") == 0) {
			mode = FLOW_MODE_MAP;
		} else if (matches(*argv, "hash") == 0) {
			mode = FLOW_MODE_HASH;
		} else if (matches(*argv, "keys") == 0) {
			NEXT_ARG();
			if (flow_parse_keys(&keys, &nkeys, *argv))
				return -1;
			addattr32(n, 4096, TCA_FLOW_KEYS, keys);
		} else if (matches(*argv, "and") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"mask\"\n");
				return -1;
			}
			transfer_bitop(&mask, &xor, tmp, 0);
		} else if (matches(*argv, "or") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"or\"\n");
				return -1;
			}
			transfer_bitop(&mask, &xor, ~tmp, tmp);
		} else if (matches(*argv, "xor") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"xor\"\n");
				return -1;
			}
			transfer_bitop(&mask, &xor, ~0, tmp);
		} else if (matches(*argv, "rshift") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"rshift\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_RSHIFT, tmp);
		} else if (matches(*argv, "addend") == 0) {
			NEXT_ARG();
			if (get_addend(&tmp, *argv, keys)) {
				fprintf(stderr, "Illegal \"addend\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_ADDEND, tmp);
		} else if (matches(*argv, "divisor") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"divisor\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_DIVISOR, tmp);
		} else if (matches(*argv, "baseclass") == 0) {
			NEXT_ARG();
			if (get_tc_classid(&tmp, *argv) || TC_H_MIN(tmp) == 0) {
				fprintf(stderr, "Illegal \"baseclass\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_BASECLASS, tmp);
		} else if (matches(*argv, "perturb") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"perturb\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_PERTURB, tmp);
		} else if (matches(*argv, "police") == 0) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_FLOW_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "action") == 0) {
			NEXT_ARG();
			if (parse_action(&argc, &argv, TCA_FLOW_ACT, n)) {
				fprintf(stderr, "Illegal \"action\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "match") == 0) {
			NEXT_ARG();
			if (parse_ematch(&argc, &argv, TCA_FLOW_EMATCHES, n)) {
				fprintf(stderr, "Illegal \"ematch\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argv++, argc--;
	}

	if (nkeys > 1 && mode != FLOW_MODE_HASH) {
		fprintf(stderr, "Invalid mode \"map\" for multiple keys\n");
		return -1;
	}
	addattr32(n, 4096, TCA_FLOW_MODE, mode);

	if (mask != ~0 || xor != 0) {
		addattr32(n, 4096, TCA_FLOW_MASK, mask);
		addattr32(n, 4096, TCA_FLOW_XOR, xor);
	}

	tail->rta_len = (void *)NLMSG_TAIL(n) - (void *)tail;
	return 0;
}