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
PROG= lpc
@ -7,4 +7,7 @@ SRCS= lpc.c cmds.c cmdtab.c
BINGRP= daemon
BINMODE=2555
LDADD+= -ledit -ltermcap
DPADD+= ${LIBEDIT} ${LIBTERMCAP}
.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
@ -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 <signal.h>
#include <setjmp.h>
#include <syslog.h>
#include <histedit.h>
#include <unistd.h>
#include <stdlib.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
*/
#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')