BSD 4_4_Lite2 release
[unix-history] / usr / src / usr.sbin / lpr / common_source / printcap.c
index 1c05280..cbbaef1 100644 (file)
-/*     printcap.c      1.3     81/06/01        */
-/* Copyright (c) 1979 Regents of the University of California */
+/*
+ * Copyright (c) 1983, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)printcap.c 8.2 (Berkeley) 4/28/95";
+#endif /* not lint */
+
+#include <sys/param.h>
+
+#include <fcntl.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include "lp.h"
+#include "pathnames.h"
+
+#ifndef BUFSIZ
 #define        BUFSIZ  1024
 #define        BUFSIZ  1024
+#endif
 #define MAXHOP 32      /* max number of tc= indirections */
 
 #define MAXHOP 32      /* max number of tc= indirections */
 
-#include <ctype.h>
-#include "local/uparm.h"
+/*
+ * getcap-style interface for the old printcap routines.
+ *
+ * !!!USE THIS INTERFACE ONLY IF YOU DON'T HAVE THE REAL GETCAP!!!
+ */
+
+static char *pbp;              /* pointer into pbuf for pgetstr() */
+static char pbuf[BUFSIZ];      /* buffer for capability strings */
+extern char line[];            /* buffer for printcap entries */
+
+int
+cgetnext(bp, db_array)
+        register char **bp;
+       char **db_array;
+{
+       int ret;
+       char *strdup();
+
+       pbp = pbuf;
+       ret = getprent(line);
+       *bp = strdup(line);
+       return (ret);
+}
+
+int
+cgetent(bp, db_array, name)
+       char **bp, **db_array, *name;
+{
+       int i;
+
+       *bp = line;
+       pbp = pbuf;
+       i = pgetent(*bp, name);
+       if (i < 0)
+               return (-2);
+       else if (i == 0)
+               return (-1);
+       else
+               return (0);
+}
+
+char *
+cgetcap(buf, cap, type)
+       char *buf, *cap;
+       int type;
+{
+       return ((char *) pgetflag(cap));
+}
+
+int
+cgetstr(buf, cap, str)
+       char *buf, *cap;
+       char **str;
+{
+       char *pgetstr __P((char *, char **));
+
+       if (pbp >= pbuf+BUFSIZ) {
+               write(2, "Capability string buffer overflow\n", 34);
+               return (-1);
+       }
+       return ((*str = pgetstr(cap, &pbp)) == NULL ? -1 : 0);
+}
+
+int
+cgetnum(buf, cap, num)
+       char *buf, *cap;
+       long *num;
+{
+       return ((*num = pgetnum(cap)) < 0 ? -1 : 0);
+}
+
+int
+cgetclose()
+{
+       void endprent __P((void));
+
+       endprent();
+       return (0);
+}
+
+
 /*
  * termcap - routines for dealing with the terminal capability data base
  *
 /*
  * termcap - routines for dealing with the terminal capability data base
  *
 #define tdecode pdecode
 #define tnchktc        pnchktc
 #define        tnamatch pnamatch
 #define tdecode pdecode
 #define tnchktc        pnchktc
 #define        tnamatch pnamatch
-#undef E_TERMCAP
-#define E_TERMCAP "/etc/printcap"
 #define V6
 #endif
 
 #define V6
 #endif
 
+static FILE *pfp = NULL;       /* printcap data base file pointer */
 static char *tbuf;
 static char *tbuf;
-static int hopcount;   /* detect infinite loops in termcap, init 0 */
-char   *tskip();
-char   *tgetstr();
-char   *tdecode();
-char   *getenv();
+static int hopcount;           /* detect infinite loops in termcap, init 0 */
+static int tf;
+
+char *tgetstr __P((char *, char **));
+static char *tskip __P((char *));
+static char *tdecode __P((char *, char **));
+
+/*
+ * Similar to tgetent except it returns the next enrty instead of
+ * doing a lookup.
+ */
+int
+getprent(bp)
+       register char *bp;
+{
+       register int c, skip = 0;
+
+       if (pfp == NULL && (pfp = fopen(_PATH_PRINTCAP, "r")) == NULL)
+               return(-1);
+       tbuf = bp;
+       for (;;) {
+               switch (c = getc(pfp)) {
+               case EOF:
+                       fclose(pfp);
+                       pfp = NULL;
+                       return(0);
+               case '\n':
+                       if (bp == tbuf) {
+                               skip = 0;
+                               continue;
+                       }
+                       if (bp[-1] == '\\') {
+                               bp--;
+                               continue;
+                       }
+                       *bp = '\0';
+                       return(1);
+               case '#':
+                       if (bp == tbuf)
+                               skip++;
+               default:
+                       if (skip)
+                               continue;
+                       if (bp >= tbuf+BUFSIZ) {
+                               write(2, "Termcap entry too long\n", 23);
+                               *bp = '\0';
+                               return(1);
+                       }
+                       *bp++ = c;
+               }
+       }
+}
+
+void
+endprent()
+{
+       if (pfp != NULL) {
+               /*
+                * Can't use fclose here because on POSIX-compliant
+                * systems, fclose() causes the file pointer of the
+                * underlying file descriptor (which is possibly shared
+                * with a parent process) to be adjusted, and this
+                * reeks havoc in the parent because it doesn't know
+                * the file pointer has changed.
+                */
+               (void) close(fileno(pfp));
+               pfp = NULL;
+       }
+}
 
 /*
  * Get an entry for terminal name in buffer bp,
  * from the termcap file.  Parse is very rudimentary;
  * we just notice escaped newlines.
  */
 
 /*
  * Get an entry for terminal name in buffer bp,
  * from the termcap file.  Parse is very rudimentary;
  * we just notice escaped newlines.
  */
+int
 tgetent(bp, name)
        char *bp, *name;
 {
 tgetent(bp, name)
        char *bp, *name;
 {
@@ -55,11 +246,8 @@ tgetent(bp, name)
        register int c;
        register int i = 0, cnt = 0;
        char ibuf[BUFSIZ];
        register int c;
        register int i = 0, cnt = 0;
        char ibuf[BUFSIZ];
-       char *cp2;
-       int tf;
 
        tbuf = bp;
 
        tbuf = bp;
-       tf = 0;
 #ifndef V6
        cp = getenv("TERMCAP");
        /*
 #ifndef V6
        cp = getenv("TERMCAP");
        /*
@@ -76,16 +264,14 @@ tgetent(bp, name)
                                strcpy(bp,cp);
                                return(tnchktc());
                        } else {
                                strcpy(bp,cp);
                                return(tnchktc());
                        } else {
-                               tf = open(E_TERMCAP, 0);
+                               tf = open(_PATH_PRINTCAP, 0);
                        }
                } else
                        tf = open(cp, 0);
        }
                        }
                } else
                        tf = open(cp, 0);
        }
-       if (tf==0)
-               tf = open(E_TERMCAP, 0);
-#else
-       tf = open(E_TERMCAP, 0);
 #endif
 #endif
+       if (tf==0)
+               tf = open(_PATH_PRINTCAP, 0);
        if (tf < 0)
                return (-1);
        for (;;) {
        if (tf < 0)
                return (-1);
        for (;;) {
@@ -95,6 +281,7 @@ tgetent(bp, name)
                                cnt = read(tf, ibuf, BUFSIZ);
                                if (cnt <= 0) {
                                        close(tf);
                                cnt = read(tf, ibuf, BUFSIZ);
                                if (cnt <= 0) {
                                        close(tf);
+                                       tf = 0;
                                        return (0);
                                }
                                i = 0;
                                        return (0);
                                }
                                i = 0;
@@ -119,8 +306,13 @@ tgetent(bp, name)
                 * The real work for the match.
                 */
                if (tnamatch(name)) {
                 * The real work for the match.
                 */
                if (tnamatch(name)) {
-                       close(tf);
-                       return(tnchktc());
+                       lseek(tf, 0L, 0);
+                       i = tnchktc();
+                       if (tf) {
+                               close(tf);
+                               tf = 0;
+                       }
+                       return(i);
                }
        }
 }
                }
        }
 }
@@ -132,6 +324,7 @@ tgetent(bp, name)
  * entries to say "like an HP2621 but doesn't turn on the labels".
  * Note that this works because of the left to right scan.
  */
  * entries to say "like an HP2621 but doesn't turn on the labels".
  * Note that this works because of the left to right scan.
  */
+int
 tnchktc()
 {
        register char *p, *q;
 tnchktc()
 {
        register char *p, *q;
@@ -179,6 +372,7 @@ tnchktc()
  * against each such name.  The normal : terminator after the last
  * name (before the first field) stops us.
  */
  * against each such name.  The normal : terminator after the last
  * name (before the first field) stops us.
  */
+int
 tnamatch(np)
        char *np;
 {
 tnamatch(np)
        char *np;
 {
@@ -225,6 +419,7 @@ tskip(bp)
  * a # character.  If the option is not found we return -1.
  * Note that we handle octal numbers beginning with 0.
  */
  * a # character.  If the option is not found we return -1.
  * Note that we handle octal numbers beginning with 0.
  */
+int
 tgetnum(id)
        char *id;
 {
 tgetnum(id)
        char *id;
 {
@@ -258,6 +453,7 @@ tgetnum(id)
  * of the buffer.  Return 1 if we find the option, or 0 if it is
  * not given.
  */
  * of the buffer.  Return 1 if we find the option, or 0 if it is
  * not given.
  */
+int
 tgetflag(id)
        char *id;
 {
 tgetflag(id)
        char *id;
 {