Add libedit command line history capability to lpc(8).

This commit is contained in:
garbled 2006-01-12 17:53:03 +00:00
parent 43e6e3abd2
commit 53df3fea02
2 changed files with 79 additions and 45 deletions

View File

@ -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 # @(#)Makefile 8.1 (Berkeley) 6/6/93
PROG= lpc PROG= lpc
@ -7,4 +7,7 @@ SRCS= lpc.c cmds.c cmdtab.c
BINGRP= daemon BINGRP= daemon
BINMODE=2555 BINMODE=2555
LDADD+= -ledit -ltermcap
DPADD+= ${LIBEDIT} ${LIBTERMCAP}
.include <bsd.prog.mk> .include <bsd.prog.mk>

View File

@ -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 * Copyright (c) 1983, 1993
@ -37,7 +37,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\
#if 0 #if 0
static char sccsid[] = "@(#)lpc.c 8.3 (Berkeley) 4/28/95"; static char sccsid[] = "@(#)lpc.c 8.3 (Berkeley) 4/28/95";
#else #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
#endif /* not lint */ #endif /* not lint */
@ -47,6 +47,7 @@ __RCSID("$NetBSD: lpc.c,v 1.17 2005/11/28 03:26:06 christos Exp $");
#include <signal.h> #include <signal.h>
#include <setjmp.h> #include <setjmp.h>
#include <syslog.h> #include <syslog.h>
#include <histedit.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -66,11 +67,10 @@ __RCSID("$NetBSD: lpc.c,v 1.17 2005/11/28 03:26:06 christos Exp $");
* lpc -- line printer control program * lpc -- line printer control program
*/ */
#define MAX_CMDLINE 200
#define MAX_MARGV 20 #define MAX_MARGV 20
int fromatty; int fromatty;
char cmdline[MAX_CMDLINE]; char *cmdline;
int margc; int margc;
char *margv[MAX_MARGV]; char *margv[MAX_MARGV];
int top; int top;
@ -78,18 +78,22 @@ uid_t uid, euid;
jmp_buf toplevel; jmp_buf toplevel;
History *hist;
HistEvent he;
EditLine *elptr;
static void cmdscanner(int); static void cmdscanner(int);
static struct cmd *getcmd(const char *); static struct cmd *getcmd(const char *);
static void intr(int); static void intr(int);
static void makeargv(void); static void makeargv(void);
static int ingroup(const char *); static int ingroup(const char *);
int main(int, char *p[]); int main(int, char *p[]);
const char *prompt(void);
static int parse(char *, char *p[], int);
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
struct cmd *c;
euid = geteuid(); euid = geteuid();
uid = getuid(); uid = getuid();
seteuid(uid); seteuid(uid);
@ -97,21 +101,8 @@ main(int argc, char *argv[])
openlog("lpd", 0, LOG_LPR); openlog("lpd", 0, LOG_LPR);
if (--argc > 0) { if (--argc > 0) {
c = getcmd(*++argv); *argv++;
if (c == (struct cmd *)-1) { exit(!parse(*argv, argv, argc));
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);
} }
fromatty = isatty(fileno(stdin)); fromatty = isatty(fileno(stdin));
top = setjmp(toplevel) == 0; 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 static void
intr(int signo) intr(int signo)
{ {
el_end(elptr);
history_end(hist);
if (!fromatty) if (!fromatty)
exit(0); exit(0);
longjmp(toplevel, 1); longjmp(toplevel, 1);
} }
const char *
prompt(void)
{
return ("lpc> ");
}
/* /*
* Command parser. * Command parser.
*/ */
static void static void
cmdscanner(int tp) cmdscanner(int tp)
{ {
struct cmd *c; int scratch;
const char *elline;
if (!tp) if (!tp)
putchar('\n'); 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 (;;) { for (;;) {
if (fromatty) { cmdline = NULL;
printf("lpc> "); do {
fflush(stdout); if (((elline = el_gets(elptr, &scratch)) != NULL)
} && (scratch != 0)) {
if (fgets(cmdline, MAX_CMDLINE, stdin) == 0) history(hist, &he, H_ENTER, elline);
quit(0, NULL); cmdline = strdup(elline);
makeargv(); makeargv();
} else {
margc = 0;
break;
}
} while (margc == 0);
if (margc == 0) if (margc == 0)
break; quit(0, NULL);
c = getcmd(margv[0]); if (!parse(cmdline, margv, margc)) {
if (c == (struct cmd *)-1) { if (cmdline != NULL)
printf("?Ambiguous command\n"); free(cmdline);
continue; continue;
} }
if (c == 0) { fflush(stdout);
printf("?Invalid command\n"); if (cmdline != NULL)
continue; free(cmdline);
}
if (c->c_priv && getuid() && ingroup(LPR_OPER) == 0) {
printf("?Privileged command\n");
continue;
}
(*c->c_handler)(margc, margv);
} }
longjmp(toplevel, 0); longjmp(toplevel, 0);
} }
@ -206,10 +236,11 @@ makeargv(void)
char *cp; char *cp;
char **argp = margv; char **argp = margv;
int n = 0; int n = 0;
size_t s;
s = sizeof(char) * strlen(cmdline);
margc = 0; margc = 0;
for (cp = cmdline; *cp && (cp - cmdline) < sizeof(cmdline) && for (cp = cmdline; *cp && (cp - cmdline) < s && n < MAX_MARGV; n++) {
n < MAX_MARGV; n++) {
while (isspace((unsigned char)*cp)) while (isspace((unsigned char)*cp))
cp++; cp++;
if (*cp == '\0') if (*cp == '\0')