mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-10-05 11:20:56 +00:00

tipc is a user-space configuration tool for TIPC (Transparent Inter-process Communication). It utilizes the TIPC netlink API in the kernel to fetch data or perform actions. The tipc tool has somewhat similar syntax to the ip tool meaning that users of the ip tool should not feel that unfamiliar with this tool. Signed-off-by: Richard Alpe <richard.alpe@ericsson.com> Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
128 lines
2.4 KiB
C
128 lines
2.4 KiB
C
/*
|
|
* cmdl.c Framework for handling command line options.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version
|
|
* 2 of the License, or (at your option) any later version.
|
|
*
|
|
* Authors: Richard Alpe <richard.alpe@ericsson.com>
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include <libmnl/libmnl.h>
|
|
|
|
#include "cmdl.h"
|
|
|
|
const struct cmd *find_cmd(const struct cmd *cmds, char *str)
|
|
{
|
|
const struct cmd *c;
|
|
const struct cmd *match = NULL;
|
|
|
|
for (c = cmds; c->cmd; c++) {
|
|
if (strstr(c->cmd, str) != c->cmd)
|
|
continue;
|
|
if (match)
|
|
return NULL;
|
|
match = c;
|
|
}
|
|
|
|
return match;
|
|
}
|
|
|
|
static struct opt *find_opt(struct opt *opts, char *str)
|
|
{
|
|
struct opt *o;
|
|
struct opt *match = NULL;
|
|
|
|
for (o = opts; o->key; o++) {
|
|
if (strstr(o->key, str) != o->key)
|
|
continue;
|
|
if (match)
|
|
return NULL;
|
|
|
|
match = o;
|
|
}
|
|
|
|
return match;
|
|
}
|
|
|
|
struct opt *get_opt(struct opt *opts, char *key)
|
|
{
|
|
struct opt *o;
|
|
|
|
for (o = opts; o->key; o++) {
|
|
if (strcmp(o->key, key) == 0 && o->val)
|
|
return o;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
char *shift_cmdl(struct cmdl *cmdl)
|
|
{
|
|
int next;
|
|
|
|
if (cmdl->optind < cmdl->argc)
|
|
next = (cmdl->optind)++;
|
|
else
|
|
next = cmdl->argc;
|
|
|
|
return cmdl->argv[next];
|
|
}
|
|
|
|
/* Returns the number of options parsed or a negative error code upon failure */
|
|
int parse_opts(struct opt *opts, struct cmdl *cmdl)
|
|
{
|
|
int i;
|
|
int cnt = 0;
|
|
|
|
for (i = cmdl->optind; i < cmdl->argc; i += 2) {
|
|
struct opt *o;
|
|
|
|
o = find_opt(opts, cmdl->argv[i]);
|
|
if (!o) {
|
|
fprintf(stderr, "error, invalid option \"%s\"\n",
|
|
cmdl->argv[i]);
|
|
return -EINVAL;
|
|
}
|
|
cnt++;
|
|
o->val = cmdl->argv[i + 1];
|
|
cmdl->optind += 2;
|
|
}
|
|
|
|
return cnt;
|
|
}
|
|
|
|
int run_cmd(struct nlmsghdr *nlh, const struct cmd *caller,
|
|
const struct cmd *cmds, struct cmdl *cmdl, void *data)
|
|
{
|
|
char *name;
|
|
const struct cmd *cmd;
|
|
|
|
if ((cmdl->optind) >= cmdl->argc) {
|
|
if (caller->help)
|
|
(caller->help)(cmdl);
|
|
return -EINVAL;
|
|
}
|
|
name = cmdl->argv[cmdl->optind];
|
|
(cmdl->optind)++;
|
|
|
|
cmd = find_cmd(cmds, name);
|
|
if (!cmd) {
|
|
/* Show help about last command if we don't find this one */
|
|
if (help_flag && caller->help) {
|
|
(caller->help)(cmdl);
|
|
} else {
|
|
fprintf(stderr, "error, invalid command \"%s\"\n", name);
|
|
fprintf(stderr, "use --help for command help\n");
|
|
}
|
|
return -EINVAL;
|
|
}
|
|
|
|
return (cmd->func)(nlh, cmd, cmdl, data);
|
|
}
|