Ultrix-3.1/src/cmd/lprsetup/misc.c
/**********************************************************************
* Copyright (c) Digital Equipment Corporation 1984, 1985, 1986. *
* All Rights Reserved. *
* Reference "/usr/src/COPYRIGHT" for applicable restrictions. *
**********************************************************************/
/******************************************************************************
* SCCSID: @(#)misc.c 3.0 4/21/86
******************************************************************************/
#include "lprsetup.h"
/*********************************
* YesNo - get a yes or no answer
* Returns TRUE=(yes), FALSE=(no)
**********************************/
YesNo (def_ans)
char def_ans;
{
int ans, done;
done = FALSE;
ans = 0;
while (NOT done)
{
ans = getcmd ();
switch (ans)
{
case NOREPLY:
done = TRUE;
if (def_ans == 'y')
ans = TRUE;
else
if (def_ans == 'n')
ans = FALSE;
break;
case YES:
done = TRUE;
ans = TRUE;
break;
case NO:
case QUIT:
done = TRUE;
ans = FALSE;
break;
case HELP:
default:
printf ("\nPlease answer yes or no [%c] ", def_ans);
}
}
return (ans);
}
/******************************************************************
* UseDefault
* returns TRUE if NULL entered (meaning use default) or
* FALSE after reading text to use in place of default
******************************************************************/
UseDefault (str, def, i)
char *str, *def;
int i; /* index into table of current symbol name */
/* which is used for more specific help messages */
{
extern char symbolname[];
extern struct table tab[];
int done;
/******************
* loop until done
******************/
done = FALSE;
while (!done)
{
printf (" [%s] ? ", def);
switch (getsymbol ())
{
default: /* this should never match! */
case GOT_SYMBOL:
strcpy (str, symbolname);
return (FALSE);
break;
case QUIT:
return (QUIT);
break;
case HELP:
realhelp(i); /* more specific help */
printf (h_default); /* a general help message */
printf ("\nEnter a value for '%s'? ", tab[i].name, def);
break;
case NOREPLY:
if (str != def)
strcpy (str, def);
return (TRUE);
break;
}
}
}
/*********************************************
* realhelp
* provides specific help for a given
* symbol index.
*********************************************/
realhelp(i)
int i;
{
extern struct table tab[];
switch(i) {
case H_af:
printf(h_af);
break;
case H_br:
printf(h_br);
break;
case H_dn:
printf(h_dn);
break;
case H_du:
printf(h_du);
break;
case H_fc:
printf(h_fc);
break;
case H_ff:
printf(h_ff);
break;
case H_fo:
printf(h_fo);
break;
case H_fs:
printf(h_fs);
break;
case H_lf:
printf(h_lf);
break;
case H_lo:
printf(h_lo);
break;
case H_lp:
printf(h_lp);
break;
case H_mx:
printf(h_mx);
break;
case H_nc:
printf(h_nc);
break;
case H_of:
printf(h_of);
break;
case H_pl:
printf(h_pl);
break;
case H_pw:
printf(h_pw);
break;
case H_rw:
printf(h_rw);
break;
case H_sd:
printf(h_sd);
break;
case H_sf:
printf(h_sf);
break;
case H_sh:
printf(h_sh);
break;
case H_tr:
printf(h_tr);
break;
case H_xc:
printf(h_xc);
break;
case H_xs:
printf(h_xs);
break;
default:
printf("Sorry, no specific help is available for symbol '%s'\n",
tab[i].name);
break;
}
}
/*********************************************
* MapLowerCase
* maps the given string into lower-case.
**********************************************/
MapLowerCase (b)
char *b;
{
while (*b)
{
if (isascii (*b) && isupper (*b))
*b = tolower (*b);
b++;
}
}
HasBadChars (b)
char *b;
{
while (*b)
{
if ((NOT isalpha (*b)) && (NOT isdigit (*b)) && (*b != '_'))
return (TRUE);
b++;
}
return (FALSE);
}
/************************************************
* Print the symbol table
* print whole table, or just the 'used' symbols
*************************************************/
Print (flag)
int flag;
{
extern struct table tab[];
extern char pnum[];
extern char ptype[];
int i, j;
printf ("\n\t\tPrinter #%s ",pnum);
if (strcmp(ptype, "lp11") == 0) {
printf("- LP11 parallel interface");
}
else {
printf("- serial line interface");
}
printf("\n\t\t----------------------------------");
if (strcmp(ptype, "lp11") == 0)
printf("--"); /* add two underlines for the longer message */
if (strlen(pnum) > 1)
printf("-"); /* add one for printers numbered 10...99 */
printf ("\nSymbol ");
if (flag == ALL)
printf ("used ");
printf (" type value\n");
printf ("------ ");
if (flag == ALL)
printf ("---- "); /* under 'used' */
printf (" ---- -----\n");
/*************************************************
* for each symbol, print name, value, used, type
**************************************************/
for (i=0; tab[i].name != 0; i++)
{
/* don't print it, if not being used now */
if ((flag == USED) && (tab[i].used == NO))
continue;
printf (" %s ", tab[i].name);
if (flag == ALL)
printf ("%s", tab[i].used == YES ? "YES " : " NO ");
switch (tab[i].stype)
{
case BOOL:
printf (" BOOL ");
break;
case INT:
printf (" INT ");
break;
case STR:
printf (" STR ");
break;
default:
printf (" ??? ??????\n");
continue; /* get next symbol */
}
/***
if ((flag == ALL) && (tab[i].used == NO)) {
printf("\n");
continue;
}
***/
if ((tab[i].nvalue != 0) && (tab[i].nvalue[0] != '\0')) {
printf ("* %s", tab[i].nvalue);
}
else if ((tab[i].svalue != 0) && (tab[i].svalue[0] != '\0')) {
printf (" %s", tab[i].svalue);
}
printf("\n"); /* end the line */
}
}
/********************************************************************
* Verified
* print the current printcap data, ask if it is OK, and return
* TRUE if it is OK, otherwise false.
*********************************************************************/
Verified ()
{
extern char pnum[];
/*
* Clear all waiting input and output chars.
* Actually we just want to clear any waiting input chars so
* we have a chance to see the values before confirming them.
* We have to sleep a second to let waiting output chars print.
*/
sleep (1);
ioctl (0, TIOCFLUSH, 0);
Print (USED); /* print values being used in current
configuration */
printf ("\nAre these the final values for printer %s ? [y] ", pnum);
fflush (stdout);
if (YesNo ('y') == TRUE) {
printf("\n");
return (TRUE);
}
else {
printf("\n");
return (FALSE);
}
}
/********************************************
* DoSymbol - adds/modifies symbols.
********************************************/
DoSymbol ()
{
extern struct table tab[]; /* default printer table */
extern char symbolname[]; /* getcmd result */
extern char oldfilter[]; /* print filter before modify */
extern char ptype[]; /* for checking on 'af' use */
extern char isnotused[]; /* "...feature is not used in LP11... */
char newval[LEN]; /* new value entered */
char *addr, *curval; /* malloc and current value */
int i, done = FALSE;
/*
* find the symbol, print current value, and
* ask for the new value, or initial value,
* if any.
*/
if (strlen (symbolname) > 2)
{
printf ("\nSymbol name '%s' is too long!\n", symbolname);
return;
}
/* symbolname contains the line just read from stdin */
for (i = 0; tab[i].name != 0; i++)
{
if (strcmp (tab[i].name, symbolname) == 0)
{
curval = tab[i].nvalue ? tab[i].nvalue : tab[i].svalue;
break;
}
}
if (tab[i].name == 0)
{
printf("\nSymbol '%s' not found. Use the 'list' command for a\n",
symbolname);
printf("complete list of all of the symbols and their defaults.\n");
return(ERROR);
}
/*
* Check for symbols not used with LP11 interface:
*/
/* accouting file (af) */
if ((strcmp(symbolname, "af") == 0) && (strcmp(ptype, "lp11") == 0)) {
printf("\nThe accounting file (af) ");
printf(isnotused);
/***
[ The accounting file (af) ] feature is not used with the
LP11 parallel line printer interface. You would only
specify this symbol for a printer which is connected via
a serial terminal line.
***/
return(0);
}
/* baud rate (br) */
if ((strcmp(symbolname, "br") == 0) && (strcmp(ptype, "lp11") == 0)) {
printf("\nThe baud rate (br) ");
printf(isnotused);
return(0);
}
/* clear flags (fc) */
if ((strcmp(symbolname, "fc") == 0) && (strcmp(ptype, "lp11") == 0)) {
printf("\nThe clear flag bits (fc) ");
printf(isnotused);
return(0);
}
/* set flags (fs) */
if ((strcmp(symbolname, "fs") == 0) && (strcmp(ptype, "lp11") == 0)) {
printf("\nThe set flag bits (fs) ");
printf(isnotused);
return(0);
}
/* no control chars (nc) */
if ((strcmp(symbolname, "nc") == 0) && (strcmp(ptype, "lp11") == 0)) {
printf("\nThe no control characters (nc) ");
printf(isnotused);
return(0);
}
/* output filter (of) */
if ((strcmp(symbolname, "of") == 0) && (strcmp(ptype, "lp11") == 0)) {
printf("\nThe output filter (of) ");
printf(isnotused);
return(0);
}
/* page length (pl) */
if ((strcmp(symbolname, "pl") == 0) && (strcmp(ptype, "lp11") == 0)) {
printf("\nThe page length (pl) ");
printf(isnotused);
return(0);
}
/* page width (pw) */
if ((strcmp(symbolname, "pw") == 0) && (strcmp(ptype, "lp11") == 0)) {
printf("\nThe page width (pw) ");
printf(isnotused);
return(0);
}
/* clear local mode bits (xc) */
if ((strcmp(symbolname, "xc") == 0) && (strcmp(ptype, "lp11") == 0)) {
printf("\nThe clear local mode word (xc) ");
printf(isnotused);
return(0);
}
/* set local mode bits (xs) */
if ((strcmp(symbolname, "xs") == 0) && (strcmp(ptype, "lp11") == 0)) {
printf("\nThe set local mode word (xs) ");
printf(isnotused);
return(0);
}
/*
* got symbol, now prompt for new value
*/
do
{
printf ("\nEnter a new value for symbol '%s'? [%s] ",
tab[i].name, curval);
switch (getsymbol() )
{
case QUIT:
return (QUIT);
break;
case HELP:
realhelp(i); /* more specific help */
printf (h_default);
break;
case NOREPLY:
tab[i].used = YES;
done = TRUE;
break;
case GOT_SYMBOL:
default:
strcpy (newval, symbolname);
printf ("\nNew '%s' is '%s', is this correct? [y] ",
tab[i].name, newval);
if (YesNo ('y') == TRUE)
{
if (validate(i, newval) < 0) /* check if valid */
continue;
if ((addr = malloc (strlen (newval) + 1)) == NULL)
{
printf ("\nmalloc: cannot get space for symbol '%s'.\n",
tab[i].name);
return(ERROR);
}
/*
* keep track if it is a real filter (/usr/lib/ulf) or
* is just an already entered one "modifying" (/usr/lib/lp2)
*/
if (strcmp(tab[i].name, "of") == 0 && (modifying == TRUE)) {
/*
* unset modifying flag if modifying, since we have
* a new value like /usr/lib/ulf, instead of a name
* like /usr/lib/lp2.
*/
modifying = FALSE;
}
if (strcmp (newval, curval) != 0)
{
tab[i].used = YES;
tab[i].nvalue = addr;
strcpy (tab[i].nvalue, newval);
}
done = TRUE;
}
break;
}
} while (NOT done);
}
/*
* validate: check that int's are all digits; baud rates are legal ones,
* booleans can only be on/off; directory names must all start with '/'.
* returns -1 if bad, else 0.
*/
validate(i,value1)
int i;
char *value1;
{
extern struct table tab[];
int retval = OK; /* return value from this routine */
int k; /* loop counter */
char value[LEN]; /* value of the symbol just entered */
/*
* save the symbol value locally
*/
if (value1 != NULL)
strcpy(value, value1);
else
strcpy(value, ""); /* should never happen */
switch (tab[i].stype)
{
case BOOL:
/* Booleans can only be on or off */
if (!(!strcmp("on", value)
|| (! strcmp("ON", value))
|| (! strcmp("off", value))
|| (! strcmp("OFF", value))))
{
printf("\nSorry, boolean symbol '%s' can only be 'on' or 'off'\n",
tab[i].name);
retval=BAD;
}
break;
case INT:
/* check first that we have all digits */
for (k = 0; value[k]!='\0'; k++)
{
if (! isdigit(value[k]))
{
printf("\nSorry, integer symbol '%s' must contain only digits (0 - 9).\n", tab[i].name);
retval=BAD;
break;
}
}
/*
* See if BR was specified and check if it is valid
* only if we haven't encountered an error yet.
*/
if ((strcmp("br", tab[i].name) == 0) && (retval != BAD))
{
switch(atoi(value))
{
case 0:
case 50:
case 75:
case 110:
case 134:
case 150:
case 200:
case 300:
case 600:
case 1200:
case 1800:
case 2400:
case 4800:
case 9600:
case 19200:
/* case 38400: (cannot use, exceeds 32767) */
break; /* baud rate OK */
default:
printf("\nSorry, illegal baudrate: %s\n", value);
printf("\nAvailable baud rates are:\n");
printf("\t 0\t 150\t 1800\n");
printf("\t 50\t 200\t 2400\n");
printf("\t 75\t 300\t 4800\n");
printf("\t 110\t 600\t 9600\n");
printf("\t 134\t 1200\t 19200\n"); /* NOTE: no 38400 */
retval = BAD;
break;
}
}
break;
case STR:
/* check if name is special and must start with '/' */
if (!strcmp ("sd", tab[i].name) /* spool directory */
|| (!strcmp ("lp", tab[i].name)) /* device name */
|| (!strcmp ("of", tab[i].name)) /* output filter */
|| (!strcmp ("af", tab[i].name)) /* accounting file */
|| (!strcmp ("dn", tab[i].name)) /* daemon name */
|| (!strcmp ("lf", tab[i].name))) /* logfile */
{
if (value[0] != '/')
{
printf("\nSorry, the value of symbol '%s' must begin with '/'.\n",tab[i].name);
retval=BAD;
}
}
break;
default:
printf ("lprsetup: bad type %d for symbol %s.\n",tab[i].stype,tab[i].name);
retval=BAD;
}
return(retval);
}
/*****************************************************
* Read a line and return the symbol; only knows about
* quit and help, but none of the other commands.
*****************************************************/
getsymbol ()
{
extern struct cmdtyp cmdtyp[];
extern char symbolname[];
int i, length, retval;
register char *q;
char line[BUF_LINE]; /* input line */
char line2[BUF_LINE]; /* saved version of the input line */
if (fgets (line, BUF_LINE, stdin) == NULL) {
printf ("\n"); /* EOF (^D) */
return (QUIT);
}
if (line[0] == '\n') {
return (NOREPLY);
}
if (line[strlen (line) - 1] == '\n') {
line[strlen (line) - 1] = NULL;
}
for (q = line; isspace (*q); q++) {
; /* nop */
}
strcpy(line2, line); /* save original entry, including caps */
MapLowerCase(line);
length = strlen(line);
for (i = 0; cmdtyp[i].cmd_name; i++) {
if (strncmp(cmdtyp[i].cmd_name, line, length) == 0) {
retval = cmdtyp[i].cmd_id;
break;
}
}
strcpy(symbolname, line2); /* save symbol name globaly */
if ((strcmp(symbolname, "help") == 0)
|| (strcmp(symbolname, "quit") == 0)
|| (strcmp(symbolname, "?") == 0)){
return(retval); /* return command id only if quit or help */
} else {
return (GOT_SYMBOL); /* else return a symbol */
}
}
/*****************************************************
* Read a line, decode the command, return command id
* This routine knows about the full command set.
*****************************************************/
getcmd ()
{
extern struct cmdtyp cmdtyp[];
extern char symbolname[];
int i, length;
register char *q;
char line[BUF_LINE]; /* input line */
if (fgets (line, BUF_LINE, stdin) == NULL)
{ /* EOF (^D) */
printf ("\n");
return (QUIT);
}
if (line[0] == '\n')
return (NOREPLY);
if (line[strlen (line) - 1] == '\n')
line[strlen (line) - 1] = NULL;
for (q = line; isspace (*q); q++)/* strip leading blanks */
;
MapLowerCase (line);
length = strlen (line);
for (i = 0; cmdtyp[i].cmd_name; i++)
if (strncmp (cmdtyp[i].cmd_name, line, length) == 0)
return (cmdtyp[i].cmd_id);/* command id */
strcpy (symbolname, line); /* save symbol name globaly */
return (GOT_SYMBOL);
}
usage ()
{
extern char *progname;
fprintf (stderr, "\nusage: %s\n", progname);
exit (1);
}
leave (status)
int status;
{
exit (status);
}
/**************************
* free nvalue when done
**************************/
freemem ()
{
extern struct table tab[];
int i;
for (i = 0; tab[i].name != 0; ++i)
if (tab[i].nvalue > 0)
free (tab[i].nvalue);
}
/****************************************
* edit the ttys file and change the line
* to an appropriate mode (30) for printer.
* can also change it back to something else.
****************************************/
fixtty(line, mode)
char *line; /* tty10, or whatever */
char *mode; /* 00, 22, 30, or whatever */
{
FILE *fp;
printf("editing /etc/ttys file (%s%s)...\n",mode,line);
fp = Popen(EDTTY, "w");
if (fp == NULL) {
perror("popen(%s)\n", EDTTY);
fprintf(stderr, "\n/etc/ttys not edited (could not change line to %s%s).\n", mode, line);
} else {
fprintf(fp, "/^..%s/s//%s%s/\n", line, mode, line);
fprintf(fp, "w\n");
fprintf(fp, "q\n");
fflush(fp);
pclose(fp);
printf("kill -1 1\n");
kill(1, SIGHUP); /* send hangup to init */
printf("done");
}
return(OK);
}
FILE*
Popen(s1, s2)
char *s1, *s2;
{
FILE *fp;
close(1);
fp = popen(s1, s2);
dup2(3, 1);
return(fp);
}
/******************************************************************************
* end of misc.c
******************************************************************************/