?? support_tool.c
字號(hào):
/* $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;}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -