/*
+ * $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.
- */
-
-/*
+ *
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved.
*
#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
-
-#ifndef lint
-static char sccsid[] = "@(#)printcap.c 5.7 (Berkeley) 3/4/91";
-#endif /* not lint */
+#endif /* HAVE_CONFIG_H */
#include <ctype.h>
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
#include <sys/types.h>
#include <sys/stat.h>
+#ifdef HAVE_FCNTL_H
#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
#include <atalk/paths.h>
#include "printcap.h"
#ifndef BUFSIZ
#define BUFSIZ 1024
-#endif
+#endif /* ! BUFSIZ */
#define MAXHOP 32 /* max number of tc= indirections */
/*
#define tnchktc pnchktc
#define tnamatch pnamatch
#define V6
-#endif
+#endif /* PRINTCAP */
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
* 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);
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);
* 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;
cp2 = getenv("TERM");
if (cp2==(char *) 0 || strcmp(name,cp2)==0) {
strcpy(bp,cp);
- return(tnchktc());
+ return(tnchktc(cap));
} else {
tf = open(cap, 0);
}
}
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);
}
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;
* 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 */
* 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;
* 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);
}
* 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;
* 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;
}
}
-/*
- * 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;
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;
int i;
cp = *area;
- while ((c = *str++) && c != ':' && c != '|' ) {
+ while ((c = *str++) && --bufsize && c != ':' && c != '|' ) {
switch (c) {
case '^':
}
char *
-getpname( area )
- char **area;
+getpname(char **area, int bufsize)
{
- return( decodename( tbuf, area ));
+ return( decodename( tbuf, area, bufsize));
}