diff options
author | <Mark.Phalan@Sun.COM> | 2008-11-05 10:43:38 +0100 |
---|---|---|
committer | <Mark.Phalan@Sun.COM> | 2008-11-05 10:43:38 +0100 |
commit | 6d0847464d3fec218788a8cefc60dc6947328332 (patch) | |
tree | 649cd4a0d28e33c65cfc223a2a5b484fbd914507 | |
parent | dd9ccd46893ed9c4247368a00a0253d45a26311c (diff) | |
download | illumos-joyent-6d0847464d3fec218788a8cefc60dc6947328332.tar.gz |
5047971 kadmin could use libtecla for enhanced command history and editing
-rw-r--r-- | usr/src/lib/krb5/ss/Makefile.com | 4 | ||||
-rw-r--r-- | usr/src/lib/krb5/ss/execute_cmd.c | 7 | ||||
-rw-r--r-- | usr/src/lib/krb5/ss/listen.c | 172 | ||||
-rw-r--r-- | usr/src/lib/krb5/ss/parse.c | 45 | ||||
-rw-r--r-- | usr/src/lib/krb5/ss/ss_err.h | 12 | ||||
-rw-r--r-- | usr/src/lib/krb5/ss/ss_internal.h | 11 | ||||
-rw-r--r-- | usr/src/pkgdefs/SUNWkrbu/depend | 5 |
7 files changed, 223 insertions, 33 deletions
diff --git a/usr/src/lib/krb5/ss/Makefile.com b/usr/src/lib/krb5/ss/Makefile.com index 9768d5fd1a..c87da9f2c8 100644 --- a/usr/src/lib/krb5/ss/Makefile.com +++ b/usr/src/lib/krb5/ss/Makefile.com @@ -22,8 +22,6 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# LIBRARY= libss.a VERS= .1 @@ -71,7 +69,7 @@ CFLAGS += $(CCVERBOSE) -I.. DYNFLAGS += $(KRUNPATH) $(KMECHLIB) $(ZIGNORE) -LDLIBS += -lc +LDLIBS += -lc -ltecla $(PICS) := CFLAGS += $(XFFLAG) diff --git a/usr/src/lib/krb5/ss/execute_cmd.c b/usr/src/lib/krb5/ss/execute_cmd.c index 6a0030cdaf..ff68e92655 100644 --- a/usr/src/lib/krb5/ss/execute_cmd.c +++ b/usr/src/lib/krb5/ss/execute_cmd.c @@ -1,10 +1,8 @@ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Copyright 1987, 1988, 1989 by Massachusetts Institute of Technology * @@ -214,7 +212,8 @@ int ss_execute_line (sci_idx, line_ptr) } /* parse it */ - argv = ss_parse(sci_idx, line_ptr, &argc); + /* Solaris Kerberos */ + (void) ss_parse(sci_idx, line_ptr, &argc, &argv, 0); if (argc == 0) return 0; diff --git a/usr/src/lib/krb5/ss/listen.c b/usr/src/lib/krb5/ss/listen.c index a1035e9fde..f07b5d611b 100644 --- a/usr/src/lib/krb5/ss/listen.c +++ b/usr/src/lib/krb5/ss/listen.c @@ -1,10 +1,8 @@ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Listener loop for subsystem library libss.a. * @@ -23,6 +21,11 @@ #include <termios.h> #include <libintl.h> #include <sys/param.h> +/* Solaris Kerberos */ +#include <libtecla.h> + +#define MAX_LINE_LEN BUFSIZ +#define MAX_HIST_LEN 8192 static ss_data *current_info; static jmp_buf listen_jmpb; @@ -45,16 +48,101 @@ static RETSIGTYPE listen_int_handler(signo) putc('\n', stdout); longjmp(listen_jmpb, 1); } +/* Solaris Kerberos */ +typedef struct _ss_commands { + int sci_idx; + const char **cmd; + unsigned int count; +} ss_commands; + +/* + * Solaris Kerberos + * get_commands fills out a ss_commands structure with pointers + * to the top-level commands (char*) that a program supports. + * count reflects the number of commands cmd holds. Memory must + * be allocated by the caller. + */ +void get_commands(ss_commands *commands) { + const char * const *cmd; + ss_request_table **table; + ss_request_entry *request; + ss_data *info; + + commands->count = 0; + + info = ss_info(commands->sci_idx); + for (table = info->rqt_tables; *table; table++) { + for (request = (*table)->requests; + request->command_names != NULL; request++) { + for (cmd = request->command_names; + cmd != NULL && *cmd != NULL; cmd++) { + if (commands->cmd != NULL) + commands->cmd[commands->count] = *cmd; + commands->count++; + } + } + } +} + +/* + * Solaris Kerberos + * Match function used by libtecla for tab-completion. + */ +CPL_MATCH_FN(cmdmatch) { + int argc, len, ws, i; + char **argv, *l; + ss_commands *commands = data; + int ret = 0; + + /* Dup the line as ss_parse will modify the string */ + l = strdup(line); + if (l == NULL) + return (ret); + + /* Tab-completion may happen in the middle of a line */ + if (word_end != strlen(l)) + l[word_end] = '\0'; + + if (ss_parse(commands->sci_idx, l, &argc, &argv, 1)) { + free (l); + return (ret); + } + + /* Don't bother if the arg count is not 1 or 0 */ + if (argc < 2) { + len = argc ? strlen(argv[0]) : 0; + ws = word_end - len; + + for (i = 0; i < commands->count; i++) { + if (strncmp(commands->cmd[i], line + ws, len) == 0) { + ret = cpl_add_completion(cpl, line, ws, + word_end, commands->cmd[i] + len, "", " "); + if (ret) + break; + } + } + } + + free(argv); + free(l); + return (ret); +} int ss_listen (sci_idx) int sci_idx; { register char *cp; register ss_data *info; - char input[BUFSIZ]; char buffer[BUFSIZ]; char *volatile end = buffer; int code; + + /* Solaris Kerberos */ + char *input; + GetLine *gl; + GlReturnStatus ret; + ss_commands commands; + jmp_buf old_jmpb; ss_data *old_info = current_info; #ifdef POSIX_SIGNALS @@ -69,6 +157,41 @@ int ss_listen (sci_idx) current_info = info = ss_info(sci_idx); info->abort = 0; + /* Solaris Kerberos */ + gl = new_GetLine(MAX_LINE_LEN, MAX_HIST_LEN); + if (gl == NULL) { + ss_error(sci_idx, 0, dgettext(TEXT_DOMAIN, + "new_GetLine() failed.\n")); + current_info = old_info; + return (SS_ET_TECLA_ERR); + } + + commands.sci_idx = sci_idx; + commands.cmd = NULL; + + /* Find out how many commands there are */ + get_commands(&commands); + + /* Alloc space for them */ + commands.cmd = malloc(sizeof (char *) * commands.count); + if (commands.cmd == NULL) { + current_info = old_info; + gl = del_GetLine(gl); + return (ENOMEM); + } + + /* Fill-in commands.cmd */ + get_commands(&commands); + + if (gl_customize_completion(gl, &commands, cmdmatch) != 0 ) { + ss_error(sci_idx, 0, dgettext(TEXT_DOMAIN, + "failed to register completion function.\n")); + free(commands.cmd); + current_info = old_info; + gl = del_GetLine(gl); + return (SS_ET_TECLA_ERR); + } + #ifdef POSIX_SIGNALS csig.sa_handler = (RETSIGTYPE (*)())0; sigemptyset(&nmask); @@ -97,6 +220,19 @@ int ss_listen (sci_idx) #else (void) sigsetmask(mask); #endif + + /* + * Solaris Kerberos: + * Let libtecla deal with SIGINT when it's doing its own processing + * otherwise the input line won't be cleared on SIGINT. + */ + if (gl_trap_signal(gl, SIGINT, GLS_DONT_FORWARD, GLS_ABORT, NULL)) { + ss_error(sci_idx, 0, dgettext(TEXT_DOMAIN, + "Failed to trap SIGINT.\n")); + code = SS_ET_TECLA_ERR; + goto egress; + } + while(!info->abort) { print_prompt(); *end = '\0'; @@ -112,10 +248,25 @@ int ss_listen (sci_idx) if (sig_cont == print_prompt) sig_cont = old_sig_cont; #endif - if (fgets(input, BUFSIZ, stdin) != input) { - code = SS_ET_EOF; - goto egress; - } + + /* Solaris Kerberos */ + input = gl_get_line(gl, info->prompt, NULL, -1); + ret = gl_return_status(gl); + + switch (ret) { + case (GLR_SIGNAL): + gl_abandon_line(gl); + continue; + case (GLR_EOF): + info->abort = 1; + continue; + case (GLR_ERROR): + ss_error(sci_idx, 0, dgettext(TEXT_DOMAIN, + "Failed to read line: %s\n"), gl_error_message(gl, NULL, 0)); + info->abort = 1; + code = SS_ET_TECLA_ERR; + goto egress; + } cp = strchr(input, '\n'); if (cp) { *cp = '\0'; @@ -148,6 +299,11 @@ int ss_listen (sci_idx) } code = 0; egress: + + /* Solaris Kerberos */ + free(commands.cmd); + gl = del_GetLine(gl); + #ifdef POSIX_SIGNALS sigaction(SIGINT, &isig, (struct sigaction *)0); #else diff --git a/usr/src/lib/krb5/ss/parse.c b/usr/src/lib/krb5/ss/parse.c index 9edb3ffe37..fa0dbb989c 100644 --- a/usr/src/lib/krb5/ss/parse.c +++ b/usr/src/lib/krb5/ss/parse.c @@ -1,17 +1,32 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Copyright 1987, 1988 by MIT Student Information Processing Board * * For copyright info, see copyright.h. */ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + #include "ss_internal.h" #include "copyright.h" #include <errno.h> enum parse_mode { WHITESPACE, TOKEN, QUOTED_STRING }; + +/* + * Solaris Kerberos: + * ss_parse has been modified slightly from the original in two ways. + * 1) A new parameter "quiet" has been added which is used to silence + * error or warning messages. + * 2) ss_parse now returns an error status instead of argv - this is to + * allow an error to be distinguished from no tokens when parsing an empty + * string. + * Both of these changes allow ss_parse to be used during tab-completion. + */ + /* * parse(line_ptr, argc_ptr) * @@ -23,18 +38,21 @@ enum parse_mode { WHITESPACE, TOKEN, QUOTED_STRING }; * Pointer to text string to be parsed. * argc_ptr (int *) * Where to put the "argc" (number of tokens) value. + * argv_ptr (char ***) + * Where to put the series of pointers to parsed tokens. * Returns: - * argv (char **) - * Series of pointers to parsed tokens. + * error (0 - success, non-zero on failure) */ #define NEW_ARGV(old,n) (char **)realloc((char *)old,\ (unsigned)(n+2)*sizeof(char*)) -char **ss_parse (sci_idx, line_ptr, argc_ptr) +int ss_parse (sci_idx, line_ptr, argc_ptr, argv_ptr, quiet) int sci_idx; register char *line_ptr; int *argc_ptr; + char ***argv_ptr; + int quiet; { register char **argv, *cp; register int argc; @@ -42,9 +60,11 @@ char **ss_parse (sci_idx, line_ptr, argc_ptr) argv = (char **) malloc (sizeof(char *)); if (argv == (char **)NULL) { - ss_error(sci_idx, errno, "Can't allocate storage"); + if (!quiet) + ss_error(sci_idx, errno, "Can't allocate storage"); *argc_ptr = 0; - return(argv); + *argv_ptr = argv; + return(ENOMEM); } *argv = (char *)NULL; @@ -102,11 +122,13 @@ char **ss_parse (sci_idx, line_ptr, argc_ptr) } while (parse_mode == QUOTED_STRING) { if (*line_ptr == '\0') { - ss_error (sci_idx, 0, - "Unbalanced quotes in command line"); + if (!quiet) + ss_error (sci_idx, 0, + "Unbalanced quotes in command line"); free (argv); *argc_ptr = 0; - return NULL; + *argv_ptr = NULL; + return (-1); } else if (*line_ptr == '"') { if (*++line_ptr == '"') { @@ -133,5 +155,6 @@ end_of_line: argv[i] ? argv[i] : "<NULL>"); } #endif - return(argv); + *argv_ptr = argv; + return(0); } diff --git a/usr/src/lib/krb5/ss/ss_err.h b/usr/src/lib/krb5/ss/ss_err.h index 9c02db50d2..5dde9c5ed7 100644 --- a/usr/src/lib/krb5/ss/ss_err.h +++ b/usr/src/lib/krb5/ss/ss_err.h @@ -1,4 +1,12 @@ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Solaris Kerberos: + * This file is not generated automatically for Solaris Kerberos + */ /* * ss_err.h: * This file is automatically generated; please do not edit it. @@ -15,6 +23,8 @@ #define SS_ET_NO_HELP_FILE (748809L) #define SS_ET_ESCAPE_DISABLED (748810L) #define SS_ET_UNIMPLEMENTED (748811L) +/* Solaris Kerberos */ +#define SS_ET_TECLA_ERR (748812L) #define ERROR_TABLE_BASE_ss (748800L) /* for compatibility with older versions... */ diff --git a/usr/src/lib/krb5/ss/ss_internal.h b/usr/src/lib/krb5/ss/ss_internal.h index 43431797a3..080bcd09a8 100644 --- a/usr/src/lib/krb5/ss/ss_internal.h +++ b/usr/src/lib/krb5/ss/ss_internal.h @@ -1,11 +1,15 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Copyright 1987, 1988 by MIT Student Information Processing Board * * For copyright information, see copyright.h. */ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + + #ifndef _ss_ss_internal_h #define _ss_ss_internal_h __FILE__ #include <stdio.h> @@ -91,7 +95,8 @@ typedef struct _ss_data { /* init values */ (*code_ptr=0,ss_info(sci_idx)->current_request) void ss_unknown_function(); void ss_delete_info_dir(); -char **ss_parse (int, char *, int *); +/* Solaris Kerberos */ +int ss_parse (int, char *, int *, char ***, int); ss_abbrev_info *ss_abbrev_initialize (char *, int *); void ss_page_stdin (void); int ss_pager_create (void); diff --git a/usr/src/pkgdefs/SUNWkrbu/depend b/usr/src/pkgdefs/SUNWkrbu/depend index 0255ff633d..b0af117aee 100644 --- a/usr/src/pkgdefs/SUNWkrbu/depend +++ b/usr/src/pkgdefs/SUNWkrbu/depend @@ -1,5 +1,5 @@ # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # CDDL HEADER START @@ -21,8 +21,6 @@ # # CDDL HEADER END # -# ident "%Z%%M% %I% %E% SMI" -# # This package information file defines software dependencies associated # with the pkg. You can define three types of pkg dependencies with this file: # P indicates a prerequisite for installation @@ -52,3 +50,4 @@ P SUNWcsl Core Solaris Libraries P SUNWkrbr Kerberos version 5 support (Root) P SUNWgss GSSAPI V2 P SUNWgssc GSSAPI CONFIG V2 +P SUNWtecla Tecla command-line editing library |