summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author <Mark.Phalan@Sun.COM>2008-11-05 10:43:38 +0100
committer <Mark.Phalan@Sun.COM>2008-11-05 10:43:38 +0100
commit6d0847464d3fec218788a8cefc60dc6947328332 (patch)
tree649cd4a0d28e33c65cfc223a2a5b484fbd914507
parentdd9ccd46893ed9c4247368a00a0253d45a26311c (diff)
downloadillumos-joyent-6d0847464d3fec218788a8cefc60dc6947328332.tar.gz
5047971 kadmin could use libtecla for enhanced command history and editing
-rw-r--r--usr/src/lib/krb5/ss/Makefile.com4
-rw-r--r--usr/src/lib/krb5/ss/execute_cmd.c7
-rw-r--r--usr/src/lib/krb5/ss/listen.c172
-rw-r--r--usr/src/lib/krb5/ss/parse.c45
-rw-r--r--usr/src/lib/krb5/ss/ss_err.h12
-rw-r--r--usr/src/lib/krb5/ss/ss_internal.h11
-rw-r--r--usr/src/pkgdefs/SUNWkrbu/depend5
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