⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 support_tool.c

📁 mobile ip 在linux下的一种实现
💻 C
字号:
/* $Id: support_tool.c,v 1.22 2001/09/08 16:20:06 jm Exp $ * Dynamics core support tool implementation * * Dynamic hierarchial IP tunnel * Copyright (C) 1998-2001, Dynamics group * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#ifndef __USE_BSD#define __USE_BSD /* Add strncasecmp() */#endif#include <string.h>#include <stdlib.h>#include <signal.h>#include <assert.h>#include <getopt.h>#include <unistd.h>#ifdef USE_LIBREADLINE#include <readline/readline.h>#include <readline/history.h>#endif#include "support_tool.h"#include "util.h"#define ASSERT assert#define DEBUG#define MAX(x,y) ( ( (x) > (y) ) ? (x) : (y) )#define MIN(x,y) ( ( (x) < (y) ) ? (x) : (y) )#define BUFSIZE 1024#define MAXARGS 8#define CMDLEN  32#define HELPTEXT_QUIT "Usage\n\tquit\n\texit\nDescription\n\tQuits program.\n"#define HELPTEXT_HELP "Usage\n\thelp [<command>]\nDescription\n"\"\tDisplay help screen for the command.\n"\"\tIf no command is specified, all commands will be listed.\n"/* command item stores information about a particular command. It's * used to match command string to processing function */struct command_item {	char cmd[CMDLEN+1];  /* name of command */	int unique; /* unique length of command name */	void (*func)(int argc, char *argv[]); /* processing function */	char *help; /* help text (may be NULL) */	struct tool_cmd_completion *completions;	struct command_item *next; /* next command in list */};static int quit; /* Stop flag: if non-zero, the program should stop */static int monitor_delay;    /* If non-zero, pecifies the monitoring interval			      * in seconds */static char monitor_command[BUFSIZE+1]; /* buffer for monitor command */static int executing; /* is a command being executed?  */static struct command_item *commands = NULL; /* command info list */int interactive = 0;/* *  Functions */void cleanup(void);void signal_handler(int sig);void init(void);void clear_commands(void);void set_default_commands(void);void process_string(char *);void process_command(int argc, char *argv[]);/* * Handler for interrupt signal. * If monitoring is on, break it and return to normal * command state. Else interrupt the program. */void signal_handler(int sig){	printf("Interrupted\n");	if (monitor_delay)		monitor_delay = 0;	else if (executing){		/* set executing to false to allow user to		 * interrupt the program, if command handler won't return.		 */		executing = 0;	} else {		cleanup();		exit(0);	}}#if USE_LIBREADLINEstatic char *dynamics_rl_completion(char *text, int state){	static struct command_item *start = NULL;	int len;	struct command_item *item;	if (text == NULL)		return NULL;	len = strlen(text);	if (state == 0)		start = commands;	item = start;	while (item != NULL) {		if (strncmp(text, item->cmd, len) == 0) {			start = item->next;			return strdup(item->cmd);		}		item = item->next;	}	return NULL;}static struct tool_cmd_completion *dynamics_rl_tmp_completions = NULL;static char *dynamics_rl_get_completions(char *text, int state){	int len;	static int pos = 0;	if (dynamics_rl_tmp_completions == NULL)		return NULL;	if (text == NULL)		return NULL;	if (state == 0)		pos = 0;	len = strlen(text);	while (dynamics_rl_tmp_completions[pos].cmd != NULL) {		if (strncmp(text, dynamics_rl_tmp_completions[pos].cmd,			    strlen(text)) == 0) {			char *ret = dynamics_rl_tmp_completions[pos].cmd;			pos++;			return strdup(ret);		}		pos++;	}	return NULL;}#ifdef HAVE_RL_COMPLETION_MATCHES#define completion_matches(t, m) \	rl_completion_matches((t), (rl_compentry_func_t *) (m))#endifstatic char **dynamics_rl_subcompletion(struct command_item *cmd, char *text,					int start){	int i, words = 0;	struct tool_cmd_completion *pos;	if (cmd->completions == NULL)		return NULL;	/* FIX: iterate through command arguments for later items */	for (i = 0; i < start; i++) {		if (i > 0 && isspace(rl_line_buffer[i]) &&		    !isspace(rl_line_buffer[i - 1]))			words++;	}	pos = cmd->completions;	while (words > 1 && pos != NULL) {		pos = pos->sub;		words--;	}	dynamics_rl_tmp_completions = pos;	return completion_matches(text, dynamics_rl_get_completions);}static char **dynamics_rl_attempted(char *text, int start, int end){	struct command_item *item;	if (start == 0)		return completion_matches(text, dynamics_rl_completion);	item = commands;	while (item != NULL) {		int len = strlen(item->cmd);		if (strncmp(rl_line_buffer, item->cmd, len) == 0 &&		    rl_line_buffer[len] == ' ')			return dynamics_rl_subcompletion(item, text, start);		item = item->next;	}	return NULL;}#endif /* USE_LIBREADLINE *//* * Perform initialization */void init(void){	quit = 0;	monitor_delay = 0;	executing = 0;	signal(SIGINT, signal_handler);#if USE_LIBREADLINE	rl_readline_name = "Dynamics";	rl_attempted_completion_function = (CPPFunction *)		dynamics_rl_attempted;#endif /* USE_LIBREADLINE */}/* * Clean up */void cleanup(void){	clear_commands();}/* * Input from stdin until '\n' is received. */void input_command(char *buf, int sz){#if USE_LIBREADLINE	char *tmp;	tmp = readline("> ");	if (tmp != NULL) {		add_history(tmp);		dynamics_strlcpy(buf, tmp, sz);		free(tmp);	} else		quit = 1;#else	int i = 0, n = 0;	buf[0] = 0;	write(1, "> ", 2);	fflush(NULL);	while (i < sz - 1) {		n = read(0, &buf[i], 1);		if (n == 1) {			i++;			if (buf[i-1] == '\n') break;		} else break;	}	buf[i] = 0; /* zero terminate */	if (n <= 0) quit = 1;	if (*buf == '\n') input_command(buf, sz);#endif}/* * Select handling function from command list and * call handling function. */void process_command(int argc, char *argv[]){	int n;	struct command_item *p;	if (argc < 1)		return;	p = commands;	while (p != NULL) {		n = MAX(strlen(argv[0]), p->unique);		n = MIN(strlen(p->cmd) + 1, n);		if (strncasecmp(p->cmd, argv[0], n) == 0) {			executing = 1;			if (p->func != NULL)				(*p->func)(argc, argv);			executing = 0;			return;		}		p = p->next;	}	printf("Illegal command: %s\n", argv[0]);}/* * Split command string to separate arguments and * call processing function. */void process_string(char *str){	char *p = str;	int argc = 0;	char *argv[MAXARGS];	ASSERT(str);	/* split to args */	while (*p != 0 && argc < MAXARGS) {		while (*p == ' ' || *p == '\t') p++;		if (*p == 0 || *p == '\n') break;		argv[argc] = p;		p += strcspn(p, " \t\n");		if (*p != 0) {			*p = 0;			p++;		}		argc++;	}	if (argc) process_command(argc, argv);}/* * Tool main */int tool_main(int argc, char *argv[]){	char cmdbuf[BUFSIZE+1];	*cmdbuf = 0;	init();	set_default_commands();	if (!interactive) {		process_command(argc, argv);		quit = 1;	}#if USE_LIBREADLINE	using_history();#endif	while (!quit) {		if (monitor_delay == 0 ||		    (sleep(monitor_delay) != 0))			input_command(cmdbuf, BUFSIZE);		else			dynamics_strlcpy(cmdbuf, monitor_command, BUFSIZE);		if (!quit)			process_string(cmdbuf);	}	cleanup();	return 0;}/* * Set quit flag */void tool_quit(void){	quit = 1;}/* * Add a command to the beginning of the command list */int tool_add_command(char *cmd, int unique,		     void (*func)(int argc, char *argv[]),		     char *help,		     struct tool_cmd_completion *completions){	struct command_item *item;	ASSERT(cmd != NULL);	ASSERT(unique > 0);	ASSERT(func != NULL);	item = (struct command_item *) malloc(sizeof(struct command_item));	if (item == NULL)		return -1;	dynamics_strlcpy(item->cmd, cmd, CMDLEN);	item->unique = unique;	item->func = func;	item->next = commands;	item->completions = completions;	item->help = help;	commands = item;	return 0;}/* * Clear command list */void clear_commands(void){	struct command_item *p;	while (commands != NULL) {		p = commands;		commands = commands->next;		free(p);	}}/* * Set monitor timeout to start monitoring mode. */void tool_monitor(char *cmd, int timeout){	ASSERT(timeout > 0);	monitor_delay = timeout;	dynamics_strlcpy(monitor_command, cmd, BUFSIZE);	monitor_command[BUFSIZE-1] = '\0';	printf("Starting monitoring, interval %d seconds. "	       "Press Ctrl-C to stop.\n",	       timeout);}void print_help(char *optarg){	struct command_item *item;	if (optarg) {		for (item = commands; item != NULL; item = item->next)			if (strcasecmp(optarg, item->cmd) == 0)				break;		if (item != NULL && item->help != NULL) {			printf("Help on %s:\n", item->cmd);			printf("%s\n", item->help);		} else printf("No help available on %s.\n", optarg);	} else {		printf("tool [OPTIONS] [COMMAND]\n"		       "options:\n[--version] [--help] "		       "[-i --interactive] [-p <path> --path=<path>]\n\n");		printf("Available commands:\n");		for (item = commands; item != NULL; item = item->next) {			printf("%s", item->cmd);			if (item->next) printf(", ");		}		printf("\n\nFor more help type '--help <command>'.\n");	}	exit(0);}/* * DEFAULT COMMANDS */static struct option#ifndef DYN_TARGET_WINDOWSconst#endiflong_options[] ={	{"help", 2, 0, 'h'},	{"version", no_argument, 0, 'v'},	{"interactive", no_argument, 0, 'i'},	{"path", required_argument, 0, 'p'},	{0, 0, 0, 0}};intparse_long_options_tools(int argc, char *argv[],			 const char *command_name,			 char *agent_path, int pathsize,			 const char *package,			 const char *version){	int c;	while ((c = getopt_long(argc, argv, "ih::p:",				long_options, (int *) 0)) != EOF) {		switch (c) {		case 'h':			if (argc >= optind)				print_help(argv[optind]);			else				print_help(NULL);		case 'v':			printf("%s (%s) %s\n", command_name, package, version);			printf("Copyright (C) 1998-2001, Dynamics group\n"			       "This program comes with NO WARRANTY,\n"			       "to the extent permitted by law.\n"			       "You may redistribute copies of this program\n"			       "under the terms of the GNU General Public "			       "License.\n"			       "For more information about these matters,\n"			       "see the files named COPYING.\n");			exit (0);		case 'i':			interactive = 1;			break;		case 'p':			dynamics_strlcpy(agent_path, optarg, pathsize);			break;		default:			/* Don't process any other long-named options.  */			break;		}	}	if (argc == optind)		interactive = 1;	return optind;}/* * Quit command */void cmd_quit(int argc, char *argv[]){	tool_quit();}/* * Show help */void cmd_help(int argc, char *argv[]){	struct command_item *item;	if (argc <= 1) {		printf("Available commands:\n");		for (item = commands; item != NULL; item = item->next) {			printf("%s", item->cmd);			if (item->next) printf(", ");		}		printf("\nFor more help type 'help <command>'.\n");	} else {		for (item = commands; item != NULL; item = item->next)			if (strcasecmp(argv[1], item->cmd) == 0)				break;		if (item != NULL && item->help != NULL) {			printf("Help on %s:\n", item->cmd);			printf("%s\n", item->help);		} else printf("No help available on %s.\n", argv[1]);	}}/* * Append default commands to end of the command list */void set_default_commands(void){	struct command_item *item, *p;	if ((item = malloc(sizeof(struct command_item))) != NULL) {		dynamics_strlcpy(item->cmd, "quit", CMDLEN);		item->unique = 4;		item->func = cmd_quit;		item->help = HELPTEXT_QUIT;		item->next = NULL;	} else return;	/* add to end of the list */	if (commands != NULL) {		for (p = commands;p->next != NULL; p = p->next);		p->next = item;	} else commands = item;	if ((item->next = malloc(sizeof(struct command_item))) != NULL) {		item = item->next;		dynamics_strlcpy(item->cmd, "exit", CMDLEN);		item->unique = 4;		item->func = cmd_quit;		item->help = HELPTEXT_QUIT;		item->next = NULL;	} else return;	if ((item->next = malloc(sizeof(struct command_item))) != NULL) {		item = item->next;		dynamics_strlcpy(item->cmd, "help", CMDLEN);		item->unique = 1;		item->func = cmd_help;		item->help = HELPTEXT_HELP;		item->next = NULL;	} else return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -