Blame tipc/cmdl.c

Packit Service 3880ab
/*
Packit Service 3880ab
 * cmdl.c	Framework for handling command line options.
Packit Service 3880ab
 *
Packit Service 3880ab
 *		This program is free software; you can redistribute it and/or
Packit Service 3880ab
 *		modify it under the terms of the GNU General Public License
Packit Service 3880ab
 *		as published by the Free Software Foundation; either version
Packit Service 3880ab
 *		2 of the License, or (at your option) any later version.
Packit Service 3880ab
 *
Packit Service 3880ab
 * Authors:	Richard Alpe <richard.alpe@ericsson.com>
Packit Service 3880ab
 */
Packit Service 3880ab
Packit Service 3880ab
#include <stdio.h>
Packit Service 3880ab
#include <string.h>
Packit Service 3880ab
#include <errno.h>
Packit Service 3880ab
Packit Service 3880ab
#include <libmnl/libmnl.h>
Packit Service 3880ab
Packit Service 3880ab
#include "cmdl.h"
Packit Service 3880ab
Packit Service 3880ab
static const struct cmd *find_cmd(const struct cmd *cmds, char *str)
Packit Service 3880ab
{
Packit Service 3880ab
	const struct cmd *c;
Packit Service 3880ab
	const struct cmd *match = NULL;
Packit Service 3880ab
Packit Service 3880ab
	for (c = cmds; c->cmd; c++) {
Packit Service 3880ab
		if (strstr(c->cmd, str) != c->cmd)
Packit Service 3880ab
			continue;
Packit Service 3880ab
		if (match)
Packit Service 3880ab
			return NULL;
Packit Service 3880ab
		match = c;
Packit Service 3880ab
	}
Packit Service 3880ab
Packit Service 3880ab
	return match;
Packit Service 3880ab
}
Packit Service 3880ab
Packit Bot 867fae
struct opt *find_opt(struct opt *opts, char *str)
Packit Service 3880ab
{
Packit Service 3880ab
	struct opt *o;
Packit Service 3880ab
	struct opt *match = NULL;
Packit Service 3880ab
Packit Service 3880ab
	for (o = opts; o->key; o++) {
Packit Service 3880ab
		if (strstr(o->key, str) != o->key)
Packit Service 3880ab
			continue;
Packit Service 3880ab
		if (match)
Packit Service 3880ab
			return NULL;
Packit Service 3880ab
Packit Service 3880ab
		match = o;
Packit Service 3880ab
	}
Packit Service 3880ab
Packit Service 3880ab
	return match;
Packit Service 3880ab
}
Packit Service 3880ab
Packit Service 3880ab
struct opt *get_opt(struct opt *opts, char *key)
Packit Service 3880ab
{
Packit Service 3880ab
	struct opt *o;
Packit Service 3880ab
Packit Service 3880ab
	for (o = opts; o->key; o++) {
Packit Service 3880ab
		if (strcmp(o->key, key) == 0 && o->val)
Packit Service 3880ab
			return o;
Packit Service 3880ab
	}
Packit Service 3880ab
Packit Service 3880ab
	return NULL;
Packit Service 3880ab
}
Packit Service 3880ab
Packit Service 3880ab
bool has_opt(struct opt *opts, char *key)
Packit Service 3880ab
{
Packit Service 3880ab
	return get_opt(opts, key) ? true : false;
Packit Service 3880ab
}
Packit Service 3880ab
Packit Service 3880ab
char *shift_cmdl(struct cmdl *cmdl)
Packit Service 3880ab
{
Packit Service 3880ab
	int next;
Packit Service 3880ab
Packit Service 3880ab
	if (cmdl->optind < cmdl->argc)
Packit Service 3880ab
		next = (cmdl->optind)++;
Packit Service 3880ab
	else
Packit Service 3880ab
		next = cmdl->argc;
Packit Service 3880ab
Packit Service 3880ab
	return cmdl->argv[next];
Packit Service 3880ab
}
Packit Service 3880ab
Packit Service 3880ab
/* Returns the number of options parsed or a negative error code upon failure */
Packit Service 3880ab
int parse_opts(struct opt *opts, struct cmdl *cmdl)
Packit Service 3880ab
{
Packit Service 3880ab
	int i;
Packit Service 3880ab
	int cnt = 0;
Packit Service 3880ab
Packit Service 3880ab
	for (i = cmdl->optind; i < cmdl->argc; i++) {
Packit Service 3880ab
		struct opt *o;
Packit Service 3880ab
Packit Service 3880ab
		o = find_opt(opts, cmdl->argv[i]);
Packit Service 3880ab
		if (!o) {
Packit Service 3880ab
			fprintf(stderr, "error, invalid option \"%s\"\n",
Packit Service 3880ab
					cmdl->argv[i]);
Packit Service 3880ab
			return -EINVAL;
Packit Service 3880ab
		}
Packit Service 3880ab
		if (o->flag & OPT_KEYVAL) {
Packit Service 3880ab
			cmdl->optind++;
Packit Service 3880ab
			i++;
Packit Service 3880ab
		}
Packit Service 3880ab
		cnt++;
Packit Service 3880ab
		o->val = cmdl->argv[i];
Packit Service 3880ab
		cmdl->optind++;
Packit Service 3880ab
	}
Packit Service 3880ab
Packit Service 3880ab
	return cnt;
Packit Service 3880ab
}
Packit Service 3880ab
Packit Service 3880ab
int run_cmd(struct nlmsghdr *nlh, const struct cmd *caller,
Packit Service 3880ab
	    const struct cmd *cmds, struct cmdl *cmdl, void *data)
Packit Service 3880ab
{
Packit Service 3880ab
	char *name;
Packit Service 3880ab
	const struct cmd *cmd;
Packit Service 3880ab
Packit Service 3880ab
	if ((cmdl->optind) >= cmdl->argc) {
Packit Service 3880ab
		if (caller->help)
Packit Service 3880ab
			(caller->help)(cmdl);
Packit Service 3880ab
		return -EINVAL;
Packit Service 3880ab
	}
Packit Service 3880ab
	name = cmdl->argv[cmdl->optind];
Packit Service 3880ab
	(cmdl->optind)++;
Packit Service 3880ab
Packit Service 3880ab
	cmd = find_cmd(cmds, name);
Packit Service 3880ab
	if (!cmd) {
Packit Service 3880ab
		/* Show help about last command if we don't find this one */
Packit Service 3880ab
		if (help_flag && caller->help) {
Packit Service 3880ab
			(caller->help)(cmdl);
Packit Service 3880ab
		} else {
Packit Service 3880ab
			fprintf(stderr, "error, invalid command \"%s\"\n", name);
Packit Service 3880ab
			fprintf(stderr, "use --help for command help\n");
Packit Service 3880ab
		}
Packit Service 3880ab
		return -EINVAL;
Packit Service 3880ab
	}
Packit Service 3880ab
Packit Service 3880ab
	return (cmd->func)(nlh, cmd, cmdl, data);
Packit Service 3880ab
}