mirror of
				https://git.proxmox.com/git/mirror_iproute2
				synced 2025-10-31 19:18:00 +00:00 
			
		
		
		
	 f63c3f9a81
			
		
	
	
		f63c3f9a81
		
	
	
	
	
		
			
			Function only used in one file. Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
		
			
				
	
	
		
			137 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			2.6 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"
 | |
| 
 | |
| static 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;
 | |
| }
 | |
| 
 | |
| bool has_opt(struct opt *opts, char *key)
 | |
| {
 | |
| 	return get_opt(opts, key) ? true : false;
 | |
| }
 | |
| 
 | |
| 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++) {
 | |
| 		struct opt *o;
 | |
| 
 | |
| 		o = find_opt(opts, cmdl->argv[i]);
 | |
| 		if (!o) {
 | |
| 			fprintf(stderr, "error, invalid option \"%s\"\n",
 | |
| 					cmdl->argv[i]);
 | |
| 			return -EINVAL;
 | |
| 		}
 | |
| 		if (o->flag & OPT_KEYVAL) {
 | |
| 			cmdl->optind++;
 | |
| 			i++;
 | |
| 		}
 | |
| 		cnt++;
 | |
| 		o->val = cmdl->argv[i];
 | |
| 		cmdl->optind++;
 | |
| 	}
 | |
| 
 | |
| 	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);
 | |
| }
 |