📄 lprsetup.c
字号:
#ifndef lintstatic char *sccsid = "@(#)lprsetup.c 4.6 ULTRIX 3/13/91";#endif/************************************************************************ * Copyright (c) Digital Equipment Corporation 1984, 1985, 1986, 1987 * * 1988, 1989. 1991 All Rights Reserved. * ************************************************************************//************************************************************** ULTRIX-32 Printer Installation/Setup Program** This program helps system administrators to set up* printers for their system. It guides through the* steps in setting up /etc/printcap, makes all of the* necessary files and directories for each printer,* and insures everything necessary for successful* printer operation was specified.*************************************************************//* * based on lprsetup program developed by John Dustin for ULTRIX-11 * Modification history: * * 06-Mar-91 Adrian Thoms * Fixed code which adds comments to /etc/printcap * * 04-Mar-91 Adrian Thoms * Replaced calls to chmod, chown, unlink, rmdir with calls to safe* * Renamed LinkFilter to DisableGetty, Added more comments. * * 03-Mar-91 Adrian Thoms * Fixed bug whereby SetVal was ignoring request to remove a * parameter AND supplying bogus value pointed to by val which is * that left by the previous SetVal call * * 03-Mar-91 Adrian Thoms * Fix modify code so that spool dir. errlog and account files are * deleted/created with correct logic * Made UnLinkSymFile prompt system manager so that file deletions * are optional * * 27-Feb-91 Adrian Thoms * Only create spool directory, account and log file if they are * specified in the printcap entry * * 26-Feb-91 Adrian Thoms * Removed unnecessary code related to chowning and chmoding ttys * Removed edit to /etc/ttys done during queue deletion * * 04-Oct-90 Adrian Thoms * New feature so that baud is only prompted for with serial devices. * Also "br", "fc", "fs", "xc", and "xs" are only included in the * entry for serial devices * * 06-Mar-90 Adrian Thoms (thoms) * Fixed null pointer problem in LAT support. * Tidied up LAT setup code to agree with latest lpd LAT code. * * 07-Nov-89 Daren Seymour (EUEG) * Added LAT support. * * 21-Jan-89 David Gray (gray) * * DJG#12 - Changed ViewPrintcap to call GetRows to determine current * size of screen or window, PrintHelp uses the same routine. * * DJG#11 - Changed the way printer synonyms are searched for when * replacing a modified printcap entry into the printcap file. The * previous version only looked at the first synonym, this version * looks at all of them. * * 19-Jan-89 David Gray (gray) * * DJG#10 - Created a new routine called UnLinkSymFile whichs * unlinks the associated file for the specified printcap parameter. * Two in particular are the "af" accounting, and "lf" error log files. * * Help information is now printed with the PrintHelp function * which is found in misc.c, PrintHelp determines the current size * of the window or screen and stops when it is full, sort of like * "more". This prevents lengthy descriptions from scrolling off screen * * 07-Jan-89 David Gray (gray) * * DJG#8 - Stops prompting for synonyms when a synonym is found * to contain blanks or tabs, ensures all synonyms are usable. * * DJG#6 - Changed ModifyEntry to allow the spooling directory to * be modified, and is correctly handled with fix DJG#5, also changed * code to correctlt handle changes for the named accounting file and * error log file. * * DJG#5 - Changed UnlinkSpooler to remove all files in the spooling * directory prior to deleting the directory itself. * * DJG#4 - Because of an earlier change (2/17/88), modify still * assumed the printer name entered was a number and thus assumed * that the actual printer name to modify was lp[num]. Now modify * uses the name actually typed by the user. * * DJG#3 - Modified code to prevent ambiguous printer types from * being selected, must specify a unique name, ie., lp could match * lp26, lp27 or lp29. Now full printer type must be entered. * Abreviations are no longer accepted. * * DJG#2 - Changed the way the lowest printer number is found and * increased the number of possible printers from 100 to as many * as you want. It performs more checking on printer names to prevent * duplicate entries from occurring. * * DJG#1 - When spooling directories, accounting files or * error log files are created, any necessary intermediate * directories along the path are created first. * * 05-Jan-88 David Gray (gray) * General Change: voided all sprintf's * * 11-Apr-88 David Gray (gray) * Modified the GetSymbol routine in misc.c to ignore default * values that are equal to "none". Added line 504. * * 17-Feb-88 David Gray (gray) * Made changes that allow printers to be identified by * any alphanumeric name. Added additional help information: * better explanations of printcap parameters, specific * information on supported printers, more info on how * accounting information is maintained. Added a new command * called view which allows /etc/printcap file to be viewed * while in lprsetup. Added ability to add comments to * /etc/printcap while running lprsetup. * * 26-Aug-87 chetal, Pradeep * Made changes so that we insert the necessary lines for * "remote" printers in the /etc/printcap. (:lp=:\) * * 8-Jul-88 Dave Maxwell (EUEG) * Addded lps40 support * * 20-Jul-88 Dave Maxwell (EUEG) * changed lps40 to printserver * changed strncmp to strcmp so printer types must be entered in full * (this prevents ambiguous types e.g. 'lp' and ensures special cases * e.g. 'remote' to be picked up later in program * * **********************************************************/#include <stdio.h>#include <sys/types.h>#include <sys/dir.h>#include <sys/stat.h>#include <sys/file.h>#include <sys/errno.h>#include <lat/lat.h>#include "lprsetup.h"#include "globals.h"long time();extern int errno;/* debug */int debug = 0;main (argc, argv)int argc;char *argv;{ int i; if (argc != 1){ fprintf (stderr, "\nusage: %s\n", progname); exit (1); } /********************** * check prerequisites **********************/ if (getuid () != 0 && !ROOTUSER) {#ifndef LOCAL printf ("\n%s: must be superuser!\n\n", progname); leave (ERROR);#endif } /* for Popen later (in misc.c) */ for (i = 3; i < 20; i++) close(i); dup2(1, 3); if (fopen (PRINTCAP, "r") == NULL) { perror (PRINTCAP); leave (ERROR); } printf ("\nULTRIX Printer Setup Program\n"); /****************** * loop until done ******************/ for (;;) { /******************************** * clear changable table values ********************************/ for (i = 0; tab[i].name != 0; ++i) { tab[i].used = NO; tab[i].nvalue = 0; } /* * clear modify flag after each time * through, used to keep track of when to * link the filter(s). */ modifying = FALSE; printf ("\nCommand < add modify delete exit view quit help >: "); strcpy(pname, ""); strcpy(pnum, ""); switch (getcmd ()) { case ADD: DoAdd (); break; case MODIFY: DoModify (); break; case DELETE: DoDelete (); break; case QUIT: printf("\n"); leave (OK); break; case HELP: PrintHelp (h_help); break; case VIEW: ViewPrintcap (); case NOREPLY: break; default: printf ("\nSorry, invalid choice. Type '?' for help.\n"); break; } freemem (); }}/****************************************** add new entry to printcap and create* corresponding special device*****************************************/DoAdd (){ int done; int status, printerNumber; /* Starting at 0 find the lowest printer number in * the printcap data base, this number will be used * for default tty's and standard file names. If * the number is 0, and is selected by the user then * the printer is assumed to be the default printer. * DJG#2 */ printerNumber = 0; printerNumber = GetLowestNumber (printerNumber); if (printerNumber == 0) { /* Check to see if "lp" currently exists */ status = pgetent (bp, "lp"); if (status == -1) badfile (PRINTCAP); else if (status == 1) /* it does exist */ /* get next lowest number */ printerNumber = GetLowestNumber (printerNumber + 1); } (void) sprintf (pnum, "%d", printerNumber); printf("\nAdding printer entry, type '?' for help.\n"); done = 0; while (! done) { printf ("\nEnter printer name to add [%s] : ", pnum); switch (getcmd ()) { case NOREPLY: strcpy(symbolname, pnum); /* he entered the default printer # */ /* no break! ...falls through to case GOT_SYMBOL: */ case GOT_SYMBOL: status = pgetent (bp, symbolname); if (status == -1) { badfile(PRINTCAP); } if (status == 1) printf("\nSorry, printer '%s' already exists.\n", symbolname); else done = TRUE; break; case QUIT: return (QUIT); break; case HELP: PrintHelp (h_doadd); break; default: printf ("\nInvalid choice. Type '?' for help.\n"); break; } } strcpy(pname, ""); if (strcmp (pnum, symbolname) == 0) { /* DJG#2 */ if (strcmp (pnum, "0") == 0) (void) sprintf (pname, "lp|lp0|0"); else (void) sprintf (pname, "lp%s|%s", pnum, pnum); } else { /* not default number DJG#2 */ (void) sprintf(pname, "%s|lp%s", symbolname, pnum); } if (AddField () != QUIT) { AddComments (); if (AddEntry () == ERROR) printf("\nError in adding printcap entry, try again.\n"); else if (AddDevice () == ERROR) printf("\nError in associating printer files/directories.\n"); } freemem (); printf("\n"); return (OK);}/************************************ modify existing printcap entry************************************/DoModify (){ int done = FALSE; int status; printf("\nModifying a printer entry, type '?' for help.\n"); while (!done) { modifying = TRUE; strcpy(pnum, ""); strcpy(pname, ""); strcpy(longname, ""); /* in case of previous modify */ printf ("\nEnter printer name to modify (or view to view printcap file): "); switch (getcmd ()) { case GOT_SYMBOL: status = pgetent (bp, symbolname); if (status == -1) { badfile(PRINTCAP); } if (status == 0) printf ("\nSorry, printer number '%s' is not in %s.\n", symbolname, PRINTCAP); else { strcpy(pnum, symbolname); strcpy(pname, symbolname); /* DJG#4 */ ModifyEntry(); done = TRUE; /* get back to main menu */ } break; case VIEW: ViewPrintcap (); break; case QUIT: done = TRUE; break; case HELP: PrintHelp (h_domod); break; case NOREPLY: break; default: printf ("\nInvalid choice, try again.\n"); break; } } freemem(); return (OK);}/************************************ delete existing printcap entry************************************/DoDelete (){ int done = FALSE; int status; int yn; printf ("\nDeleting a printer entry, type '?' for help.\n"); while (!done) { strcpy(pnum, ""); strcpy(pname, ""); printf ("\nEnter printer name to delete (or view to view printcap file): "); switch (getcmd ()) { case GOT_SYMBOL: status = pgetent (bp, symbolname); if (status == -1) { badfile(PRINTCAP); } if (status == 0) printf ("\nCannot delete printer %s, entry not found.\n", symbolname); else { strcpy(pnum, symbolname); (void) sprintf(pname, "%s", pnum); done = TRUE; } break; case VIEW: ViewPrintcap (); break; case QUIT: return (QUIT); break; case HELP: PrintHelp (h_dodel); break; case NOREPLY: break; default: printf ("\nInvalid choice, try again.\n"); } } /********************************* * read printcap into tab for * final confirmation **********************************/ CopyEntry (); Print (USED); printf ("\nDelete %s, are you sure? [n] ", pname); yn = 'n'; if (YesNo (yn) == TRUE) { DeleteEntry (); } else { printf ("\n%s not deleted.\n", pname); } freemem (); printf("\n"); return (OK);}/******************************************** Find and return the lowest printer number* in the printcap data base starting from* the number "startingNumber". DJG#2********************************************/intGetLowestNumber (startingNumber)int startingNumber;{ char pn[ALPHANUMLEN]; /* printer number string */ char lppn[ALPHANUMLEN]; /* lp name */ int pnum_done; /* loop flag */ int status; /* return for printcap query */ int printerNumber; /* lowest number found */ printerNumber = startingNumber; pnum_done = 0; while (! pnum_done) { (void) sprintf (pn, "%d", printerNumber); status = pgetent (bp, pn); if (status == -1) badfile (PRINTCAP); else if (status == 1) printerNumber ++; else { (void) sprintf (lppn, "lp%d", printerNumber); if (pgetent (bp, lppn) == 1) printerNumber ++; else pnum_done ++; } } return (printerNumber);} /********************************** Add comments to printcap file* for printer added by DoAdd**********************************/AddComments (){ int done, leave; printf ("\nAdding comments to printcap file for new printer, type '?' for help.\n"); done = FALSE; leave = FALSE; strcpy (symbolname, "n"); printf ("Do you want to add comments to the printcap file [%s] ? : ", symbolname); while (!done) { switch (getcmd()) { case NOREPLY: case NO: done = TRUE; leave = TRUE; break; case YES: case GOT_SYMBOL: done = TRUE; break; case QUIT: done = TRUE; leave = TRUE; break; case HELP: PrintHelp(h_addcmnts); strcpy (symbolname, "n"); printf ("Do you want to add comments to the printcap file [%s] ? : ", symbolname); break; default: strcpy (symbolname, "n"); printf ("Do you want to add comments to the printcap file [%s] ? : ", symbolname); break; } } if (!leave) { printf ("Enter comments below - Press RETURN on empty line to exit\n\n"); done = FALSE; for (numcomments = 0; !done && numcomments < LINES; ) { printf ("# "); switch (getcmd()) { case NOREPLY: case QUIT: done = TRUE; break; case HELP: PrintHelp (h_addcmnts); break; default: sprintf(printercomments[numcomments++], "# %.*s", COLUMNS-3, symbolname); break; } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -