]> arthur.barton.de Git - netatalk.git/blobdiff - etc/papd/printcap.c
Previous fix 9e4e07c1811edbaf3376ad6e238a1353b405002b resulted in the inability to...
[netatalk.git] / etc / papd / printcap.c
index 203269f252c9888c68ac1b0b5647615da37d3f77..9215a11139794d3765fe90803aaf98d06e106230 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: printcap.c,v 1.4 2001-06-25 20:13:45 rufustfirefly Exp $
+ * $Id: printcap.c,v 1.12 2009-10-14 02:24:05 didg Exp $
  *
  * Copyright (c) 1990,1994 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
 #include "config.h"
 #endif /* HAVE_CONFIG_H */
 
-#ifndef lint
-static char sccsid[] = "@(#)printcap.c 5.7 (Berkeley) 3/4/91";
-#endif /* not lint */
-
 #include <ctype.h>
 #include <stdio.h>
 #include <string.h>
-#ifndef HAVE_UNISTD_H
+#include <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif /* HAVE_UNISTD_H */
 #include <sys/types.h>
@@ -96,10 +94,6 @@ static char sccsid[] = "@(#)printcap.c       5.7 (Berkeley) 3/4/91";
 static FILE *pfp = NULL;       /* printcap data base file pointer */
 static char *tbuf;
 static int hopcount;           /* detect infinite loops in termcap, init 0 */
-static char    *tskip();
-char   *tgetstr();
-static char    *tdecode();
-char   *getenv();
 
 /*
  * Similar to tgetent except it returns the next entry instead of
@@ -108,18 +102,21 @@ char      *getenv();
  * Added a "cap" parameter, so we can use these calls for printcap
  * and papd.conf.
  */
-int getprent( cap, bp)
-       register char *cap;
-       register char *bp;
+int getprent( char *cap, char *bp, int bufsize)
 {
-       register int c, skip = 0;
+       register int c, skip = 0, i;
 
        if (pfp == NULL && (pfp = fopen( cap, "r")) == NULL)
                return(-1);
        tbuf = bp;
+       i = 0;
        for (;;) {
                switch (c = getc(pfp)) {
                case EOF:
+                        if (bp != tbuf) {
+                               *bp = '\0';
+                               return(1);
+                       }
                        fclose(pfp);
                        pfp = NULL;
                        return(0);
@@ -146,11 +143,18 @@ int getprent( cap, bp)
                                return(1);
                        }
                        *bp++ = c;
+                       if (++i >= bufsize) {
+                               write(2, "config file too large\n", 22);
+                               fclose(pfp);
+                               pfp = NULL;
+                               *bp = '\0';
+                               return(1);
+                       }
                }
        }
 }
 
-void endprent()
+void endprent(void)
 {
        if (pfp != NULL)
                fclose(pfp);
@@ -164,14 +168,14 @@ void endprent()
  * Added a "cap" parameter, so we can use these calls for printcap
  * and papd.conf.
  */
-int tgetent( cap, bp, name)
-       char *cap, *bp, *name;
+int tgetent(char *cap, char *bp, char *name)
 {
        register char *cp;
        register int c;
        register int i = 0, cnt = 0;
        char ibuf[BUFSIZ];
        int tf;
+       int skip;
 
        hopcount = 0;
        tbuf = bp;
@@ -190,7 +194,7 @@ int tgetent( cap, bp, name)
                        cp2 = getenv("TERM");
                        if (cp2==(char *) 0 || strcmp(name,cp2)==0) {
                                strcpy(bp,cp);
-                               return(tnchktc());
+                               return(tnchktc(cap));
                        } else {
                                tf = open(cap, 0);
                        }
@@ -199,13 +203,14 @@ int tgetent( cap, bp, name)
        }
        if (tf==0)
                tf = open(cap, 0);
-#else
+#else /* V6 */
        tf = open(cap, 0);
-#endif
+#endif /* V6 */
        if (tf < 0)
                return (-1);
        for (;;) {
                cp = bp;
+               skip = 0;
                for (;;) {
                        if (i == cnt) {
                                cnt = read(tf, ibuf, BUFSIZ);
@@ -217,12 +222,20 @@ int tgetent( cap, bp, name)
                        }
                        c = ibuf[i++];
                        if (c == '\n') {
-                               if (cp > bp && cp[-1] == '\\'){
+                               if (!skip && cp > bp && cp[-1] == '\\') {
                                        cp--;
                                        continue;
                                }
-                               break;
+                               skip = 0;
+                               if (cp == bp)
+                                       continue;
+                               else
+                                       break;
                        }
+                       if (c == '#' && cp == bp)
+                               skip++;
+                       if (skip)
+                               continue;
                        if (cp >= bp+BUFSIZ) {
                                write(2,"Termcap entry too long\n", 23);
                                break;
@@ -251,8 +264,7 @@ int tgetent( cap, bp, name)
  * Added a "cap" parameter, so we can use these calls for printcap
  * and papd.conf.
  */
-int tnchktc( cap )
-    char *cap;
+int tnchktc( char *cap)
 {
        register char *p, *q;
        char tcname[16];        /* name of similar terminal */
@@ -299,8 +311,7 @@ int tnchktc( cap )
  * against each such name.  The normal : terminator after the last
  * name (before the first field) stops us.
  */
-int tnamatch(np)
-       char *np;
+int tnamatch(char *np)
 {
        register char *Np, *Bp;
 
@@ -325,14 +336,12 @@ int tnamatch(np)
  * knowing about \: escapes or any such.  If necessary, :'s can be put
  * into the termcap file in octal.
  */
-static char *
-tskip(bp)
-       register char *bp;
+static char *tskip(char *bp)
 {
 
        while (*bp && *bp != ':')
                bp++;
-       if (*bp == ':')
+       while (*bp && *bp == ':')
                bp++;
        return (bp);
 }
@@ -345,8 +354,7 @@ tskip(bp)
  * 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;
+int tgetnum(char *id)
 {
        register int i, base;
        register char *bp = tbuf;
@@ -378,8 +386,7 @@ int tgetnum(id)
  * of the buffer.  Return 1 if we find the option, or 0 if it is
  * not given.
  */
-int tgetflag(id)
-       char *id;
+int tgetflag(char *id)
 {
        register char *bp = tbuf;
 
@@ -396,43 +403,12 @@ int tgetflag(id)
        }
 }
 
-/*
- * Get a string valued option.
- * These are given as
- *     cl=^Z
- * Much decoding is done on the strings, and the strings are
- * placed in area, which is a ref parameter which is updated.
- * No checking on area overflow.
- */
-char *
-tgetstr(id, area)
-       char *id, **area;
-{
-       register char *bp = tbuf;
-
-       for (;;) {
-               bp = tskip(bp);
-               if (!*bp)
-                       return (0);
-               if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
-                       continue;
-               if (*bp == '@')
-                       return(0);
-               if (*bp != '=')
-                       continue;
-               bp++;
-               return (tdecode(bp, area));
-       }
-}
-
 /*
  * Tdecode does the grung work to decode the
  * string capability escapes.
  */
 static char *
-tdecode(str, area)
-       register char *str;
-       char **area;
+tdecode(char *str, char **area)
 {
        register char *cp;
        register int c;
@@ -474,10 +450,36 @@ nextc:
        return (str);
 }
 
+/*
+ * Get a string valued option.
+ * These are given as
+ *     cl=^Z
+ * Much decoding is done on the strings, and the strings are
+ * placed in area, which is a ref parameter which is updated.
+ * No checking on area overflow.
+ */
+char *
+tgetstr(char *id, char **area)
+{
+       register char *bp = tbuf;
+
+       for (;;) {
+               bp = tskip(bp);
+               if (!*bp)
+                       return (NULL);
+               if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
+                       continue;
+               if (*bp == '@')
+                       return(NULL);
+               if (*bp != '=')
+                       continue;
+               bp++;
+               return (tdecode(bp, area));
+       }
+}
+
 static char *
-decodename(str, area)
-       register char *str;
-       char **area;
+decodename(char *str, char **area, int bufsize)
 {
        register char *cp;
        register int c;
@@ -485,7 +487,7 @@ decodename(str, area)
        int i;
 
        cp = *area;
-       while ((c = *str++) && c != ':' && c != '|' ) {
+       while ((c = *str++) && --bufsize && c != ':' && c != '|' ) {
                switch (c) {
 
                case '^':
@@ -520,8 +522,7 @@ nextc:
 }
 
 char *
-getpname( area )
-    char       **area;
+getpname(char **area, int bufsize)
 {
-    return( decodename( tbuf, area ));
+       return( decodename( tbuf, area, bufsize));
 }