From 53df3fea020c8d2236ec56108f2624eaffe04e10 Mon Sep 17 00:00:00 2001 From: garbled Date: Thu, 12 Jan 2006 17:53:03 +0000 Subject: [PATCH] Add libedit command line history capability to lpc(8). --- usr.sbin/lpr/lpc/Makefile | 5 +- usr.sbin/lpr/lpc/lpc.c | 119 ++++++++++++++++++++++++-------------- 2 files changed, 79 insertions(+), 45 deletions(-) diff --git a/usr.sbin/lpr/lpc/Makefile b/usr.sbin/lpr/lpc/Makefile index cc6acc20aecd..50139435c824 100644 --- a/usr.sbin/lpr/lpc/Makefile +++ b/usr.sbin/lpr/lpc/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.8 1997/10/10 09:26:38 lukem Exp $ +# $NetBSD: Makefile,v 1.9 2006/01/12 17:53:03 garbled Exp $ # @(#)Makefile 8.1 (Berkeley) 6/6/93 PROG= lpc @@ -7,4 +7,7 @@ SRCS= lpc.c cmds.c cmdtab.c BINGRP= daemon BINMODE=2555 +LDADD+= -ledit -ltermcap +DPADD+= ${LIBEDIT} ${LIBTERMCAP} + .include diff --git a/usr.sbin/lpr/lpc/lpc.c b/usr.sbin/lpr/lpc/lpc.c index 51d5becef756..9e47314684c8 100644 --- a/usr.sbin/lpr/lpc/lpc.c +++ b/usr.sbin/lpr/lpc/lpc.c @@ -1,4 +1,4 @@ -/* $NetBSD: lpc.c,v 1.17 2005/11/28 03:26:06 christos Exp $ */ +/* $NetBSD: lpc.c,v 1.18 2006/01/12 17:53:03 garbled Exp $ */ /* * Copyright (c) 1983, 1993 @@ -37,7 +37,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\ #if 0 static char sccsid[] = "@(#)lpc.c 8.3 (Berkeley) 4/28/95"; #else -__RCSID("$NetBSD: lpc.c,v 1.17 2005/11/28 03:26:06 christos Exp $"); +__RCSID("$NetBSD: lpc.c,v 1.18 2006/01/12 17:53:03 garbled Exp $"); #endif #endif /* not lint */ @@ -47,6 +47,7 @@ __RCSID("$NetBSD: lpc.c,v 1.17 2005/11/28 03:26:06 christos Exp $"); #include #include #include +#include #include #include #include @@ -66,11 +67,10 @@ __RCSID("$NetBSD: lpc.c,v 1.17 2005/11/28 03:26:06 christos Exp $"); * lpc -- line printer control program */ -#define MAX_CMDLINE 200 #define MAX_MARGV 20 int fromatty; -char cmdline[MAX_CMDLINE]; +char *cmdline; int margc; char *margv[MAX_MARGV]; int top; @@ -78,18 +78,22 @@ uid_t uid, euid; jmp_buf toplevel; +History *hist; +HistEvent he; +EditLine *elptr; + static void cmdscanner(int); static struct cmd *getcmd(const char *); static void intr(int); static void makeargv(void); static int ingroup(const char *); int main(int, char *p[]); +const char *prompt(void); +static int parse(char *, char *p[], int); int main(int argc, char *argv[]) { - struct cmd *c; - euid = geteuid(); uid = getuid(); seteuid(uid); @@ -97,21 +101,8 @@ main(int argc, char *argv[]) openlog("lpd", 0, LOG_LPR); if (--argc > 0) { - c = getcmd(*++argv); - if (c == (struct cmd *)-1) { - printf("?Ambiguous command\n"); - exit(1); - } - if (c == 0) { - printf("?Invalid command\n"); - exit(1); - } - if (c->c_priv && getuid() && ingroup(LPR_OPER) == 0) { - printf("?Privileged command\n"); - exit(1); - } - (*c->c_handler)(argc, argv); - exit(0); + *argv++; + exit(!parse(*argv, argv, argc)); } fromatty = isatty(fileno(stdin)); top = setjmp(toplevel) == 0; @@ -123,48 +114,87 @@ main(int argc, char *argv[]) } } +static int +parse(char *arg, char **pargv, int pargc) +{ + struct cmd *c; + + c = getcmd(arg); + if (c == (struct cmd *)-1) { + printf("?Ambiguous command\n"); + return(0); + } + if (c == 0) { + printf("?Invalid command\n"); + return(0); + } + if (c->c_priv && getuid() && ingroup(LPR_OPER) == 0) { + printf("?Privileged command\n"); + return(0); + } + (*c->c_handler)(pargc, pargv); + return(1); +} + static void intr(int signo) { + el_end(elptr); + history_end(hist); if (!fromatty) exit(0); longjmp(toplevel, 1); } +const char * +prompt(void) +{ + return ("lpc> "); +} + /* * Command parser. */ static void cmdscanner(int tp) { - struct cmd *c; + int scratch; + const char *elline; if (!tp) putchar('\n'); + hist = history_init(); + history(hist, &he, H_SETSIZE, 100); /* 100 elt history buffer */ + + elptr = el_init(getprogname(), stdin, stdout, stderr); + el_set(elptr, EL_EDITOR, "emacs"); + el_set(elptr, EL_PROMPT, prompt); + el_set(elptr, EL_HIST, history, hist); + el_source(elptr, NULL); + for (;;) { - if (fromatty) { - printf("lpc> "); - fflush(stdout); - } - if (fgets(cmdline, MAX_CMDLINE, stdin) == 0) - quit(0, NULL); - makeargv(); + cmdline = NULL; + do { + if (((elline = el_gets(elptr, &scratch)) != NULL) + && (scratch != 0)) { + history(hist, &he, H_ENTER, elline); + cmdline = strdup(elline); + makeargv(); + } else { + margc = 0; + break; + } + } while (margc == 0); if (margc == 0) - break; - c = getcmd(margv[0]); - if (c == (struct cmd *)-1) { - printf("?Ambiguous command\n"); + quit(0, NULL); + if (!parse(cmdline, margv, margc)) { + if (cmdline != NULL) + free(cmdline); continue; } - if (c == 0) { - printf("?Invalid command\n"); - continue; - } - if (c->c_priv && getuid() && ingroup(LPR_OPER) == 0) { - printf("?Privileged command\n"); - continue; - } - (*c->c_handler)(margc, margv); + fflush(stdout); + if (cmdline != NULL) + free(cmdline); } longjmp(toplevel, 0); } @@ -206,10 +236,11 @@ makeargv(void) char *cp; char **argp = margv; int n = 0; + size_t s; + s = sizeof(char) * strlen(cmdline); margc = 0; - for (cp = cmdline; *cp && (cp - cmdline) < sizeof(cmdline) && - n < MAX_MARGV; n++) { + for (cp = cmdline; *cp && (cp - cmdline) < s && n < MAX_MARGV; n++) { while (isspace((unsigned char)*cp)) cp++; if (*cp == '\0')