⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 named-lint.y

📁 早期freebsd实现
💻 Y
字号:
%{#include <stdio.h>#include <string.h>#ifndef YYDEBUG#define YYDEBUG 1#endif#define True 1#define False 0int	restofline=False;	/* eat till the \n */int	justtokens=0;		/* >0 - want tokens not NUM NAMES... */				/* <0 - want tokens and keywords */				/* =0 - no tokens */int lldebug=0;			/* !=0 lexical debugging */int dup_ip=0;			/* check for duplicate ip addresses */FILE *nfd;FILE *cfd;char *origin;#define MAXNAME 256char host[MAXNAME];int numrr;			/* number of RRs for this host */int numcname;			/* number of CNAME RRs for this host */char *pgm;			/* name this program is invoked by */char *inname;			/* name of the input file */extern FILE *yyin;		/* defined in scanner */extern char *yytext;		/* defined in scanner */extern int yyleng;		/* defined in scanner */struct inaddr {  unsigned char b1, b2, b3, b4;};%}%union {  int i;  char *c;  struct inaddr ia;}%token INCLUDE ORIGIN%token NUM NAME TOKEN RESTOFLINE%token IN%token A CNAME GID HINFO MB MG MINFO MR MX NS NULLRR%token PTR RP SOA TXT UID UINFO UNSPEC WKS AFSDB%token CAMPUS LOCATION MADDR PNAME OADDR%token OPHONE EXTENSION ORGANIZATION OWNER PERSON ROOM%expect 1%%input:	/* empty */	| input line comment '\n'	;line:	/* empty */	| nstmt		{ numrr++;			  if (numcname != 0 && numrr > numcname)			    yyerror("host has CNAME and other RRs"); 			}	| bstmt	| error	;comment: /* empty */	| cmnt	;cmnt:	';' restofline	;restofline: {restofline = True;} RESTOFLINE {restofline = False;}dname:	NAME		{ $<c>$=$<c>1;}	| '@'		{ $<c>$="@";}	| '.'		{ $<c>$=".";}	;bstmt:	INCLUDE token			{/* copy new filename */} 		dname			{ /* copy new origin */			  /* indicate recursive parse */			}	| INCLUDE token			{/* copy new filename */} 	| ORIGIN dname	;nstmt:	dname {(void)strcpy(host, $<c>1);  numrr = numcname = 0; }	     stmt	{(void)fprintf(nfd, "%s\n", host);}	| stmt	;stmt:	NUM IN rr	| NUM rr	| IN rr	| rr	;	services:  /* empty */	| services NAME		{/* make sure the name is a service */}	;mline:	/* empty */	| '\n'	| cmnt '\n'	;rr:	  A addr cmnt		{ 		  if (dup_ip && iskeycmnt("noaddr", $<c>3))		    (void)dup_check(host, origin, $<ia>2);		}	|  A addr		{ if (dup_ip) (void)dup_check(host, origin, $<ia>2); }	| CNAME NAME		{ 		  numcname++;		  if (nstrcmp(host, $<c>2) == 0)		      yyerror("host name and alias/CNAME are the same");		}	| GID NUM	| HINFO token token	| MB NAME	| MG NAME	| MINFO NAME	| MR NAME	| MX NUM NAME	| NS NAME	| NULLRR	| PTR NAME	| RP NAME NAME	| AFSDB NUM NAME	| SOA NAME NAME '(' mline  		NUM mline NUM mline NUM mline NUM mline NUM mline ')'	| TXT qtxtrr	| UID NUM	| UINFO '?'	| WKS addr NAME {/* check for proper protocol */} services	;qtxtrr:	'"' txtrr '"'	| txtrr	;  	txtrr:	LOCATION baddr	| MADDR token	| PNAME restofline	| OADDR baddr	| OPHONE PHONENUM	| ORGANIZATION whom	| OWNER restofline	| PERSON whom	| NAME restofline		{ /* unknown TXT RR */ }	;whom:	NAME		{register char *p;		 if ((p=strchr($<c>1, '.')) == NULL		     || nstrcmp(p,".who.rutgers.edu") != 0)		   yyerror("name doesn't end in .who.rutgers.edu");	        }	;PHONENUM: phone EXTENSION NUM {if (yyleng!=4) yyerror("illegal extension");}	| phone	;phone:	NUM {if (yyleng!=3) yyerror("illegal area code");}	    '-' NUM {if (yyleng!=3) yyerror("illegal exchange");}	    '-' NUM {if (yyleng!=4) yyerror("illegal phone number");}	;addr:	NUM '.' NUM '.' NUM '.' NUM                { 		  int i,e=0;		  if ((i=atoi($<c>1)) > 255) { e++; goto addr_r;}		  $<ia>$.b1 = i;		  if ((i=atoi($<c>3)) > 255) { e++; goto addr_r;}		  $<ia>$.b2 = i;		  if ((i=atoi($<c>5)) > 255) { e++; goto addr_r;}		  $<ia>$.b3 = i;		  if ((i=atoi($<c>7)) > 255) { e++; goto addr_r;}		  $<ia>$.b4 = i;		addr_r:		  if (e != 0)                    yyerror("illegal internet addr");		}	;baddr:	keytoks ROOM keytoks CAMPUS keytoks	;token:	{justtokens=1;} TOKEN {justtokens=0;}	;keytoks: {justtokens=-1;} toklst {justtokens=0;}	;toklst:	TOKEN	| toklst TOKEN	;%%main(argc, argv)  int argc;  char *argv[];{  extern char *optarg;  extern int optind;  int c, aerr, e;  /* command to check for duplicate host names */  static char ndup_cmd [] = "perl -e 'while (<>) {tr/A-Z/a-z/; $hosts{$_}++;'\			     -e 'if ($hosts{$_} > 1) { ' \			     -e 'print \"Duplicate host name $_\"; $v++; }' \			     -e '} exit($v);' ";  pgm = *argv;  aerr = 0;  while ((c=getopt(argc, argv, "o:iLYh?")) != -1)    switch (c) {      case 'L':	lldebug++; break;      case 'Y':#ifdef YYDEBUG      		yydebug++;#else !YYDEBUG		fprintf(stderr, "%s: not compiled with YYDEBUG, -Y ignored\n",			pgm);#endif !YYDEBUG		break;      case 'i': dup_ip++; break;      case 'o': origin = optarg; break;      case 'h':      case '?': aerr++;    }  if (aerr || ((optind+1) < argc)) {    fprintf(stderr, "usage: %s [-L] [-Y] [-o origin] [-i] [file-name]\n", pgm);    fprintf(stderr, "where:\tfile-name or stdinn is the input file\n");    fprintf(stderr, "\t-i = duplicate IP address checking\n");    fprintf(stderr, "\t-o = initialize the origin (ala $ORIGIN)\n");    fprintf(stderr, "\t-L = Lex debugging\n");    fprintf(stderr, "\t-Y = Yacc debugging\n");    exit(-1);  } else {    if (optind >= argc) {      inname = "<stdin>";    } else {      inname = argv[optind++];      yyin = fopen(inname, "r");      if (yyin == NULL) {	fprintf("%s: Can't open file named: '%s'\n", pgm, inname);	perror(pgm);	exit(-1);      }    }  }  if ((nfd = popen(ndup_cmd, "w")) == NULL) {    (void)fprintf(stderr, "%s: can't execute dup name checker\n", pgm);    perror(pgm);    exit(2);  }  if (dup_ip) {#if 0    static char dup_cmd[] = "sort -n +0 -1 +1 -2 +2 -3 +3 -4 \\\n\      | awk ' $1==l1 && $2==l2 && $3==l3 && $4==l4 { \\\n\      printf(\"duplicate IP address %d.%d.%d.%d, for: %s and %s\\n\",\\\n\                l1, l2, l3, l4, l5, $5) } \\\n\  	{ l1=$1 ; l2=$2 ; l3=$3 ; l4=$4 ; l5=$5 } ' \\\n\	| tee /tmp/named-dup$$ \n\	if [ -s /tmp/named-dup$$ ]; then \n\	  stat=1 \n\	else \n\	  stat=0 \n\        fi \n\	rm -f /tmp/named-dup$$ \n\ 	exit $stat\n";#endif    static char dup_cmd[] = "/usr/local/bin/perl ./uniq-addr";    if ((cfd = popen(dup_cmd, "w")) == NULL) {      (void)fprintf(stderr, "%s: can't execute dup checker\n", pgm);      perror(pgm);      exit(2);    }      #if 0    if ((cfd = fopen("/tmp/named-dup.raw","w")) == NULL) {      (void)fprintf(stderr, "%s: can't open dup checker file: /tmp/named-dup.raw \n", pgm);      perror(pgm);      exit(2);    }      #endif  }  (void)yyparse();  if ((e = pclose(nfd)) == -1)    yynerrs++;  else    yynerrs += (e >> 8);    if (dup_ip) {#if 1    if ((e=pclose(cfd)) == -1)#else    if ((e=fclose(cfd)) == -1)#endif      yynerrs++;    else      yynerrs += (e >> 8);	/* get the exit code not the whole status */  }  if (yynerrs != 0 )    (void)printf("%s: %d errors\n",pgm, yynerrs);  exit(yynerrs);}/* write out the record needed by the dup_ip code */dup_check(host, origin, ia)  char host[], origin[];  struct inaddr ia;{		      (void)fprintf(cfd, "%3d %3d %3d %3d %s%",		ia.b1, ia.b2, ia.b3, ia.b4,		host);  if (origin!= NULL)    (void)fprintf(cfd, ".%s\n", origin);  else    (void)fputc('\n', cfd);}/* compute the print size of a string  * if the string is printed starting at column off figure tab expansion and * count the size of the string */int prtsize(str, off)  char str[];  int off;{  register char *s;  register int c;  for (s=str, c=off; *s!=NULL; c++, s++)    if (*s == '\t')      c = (((c/8)+1)*8) - 1;  return (c);}extern int yylineno;extern char linebuf[];yyerror(s)  char s[];{  register char c;  register int i;  (void)fprintf(stderr, "%s: %s on line %d, last recognized host name %s\n", 		pgm, s, yylineno, host);  i = prtsize(linebuf, strlen(pgm)+3); /* compute bogon pointer offset */  /* reset the lexcial flags to the initial state */  justtokens=0;  restofline++;  (void)yylex();		/* read the rest of the line */  restofline=0;  (void)fprintf(stderr, "%s: '%s'\n", pgm, linebuf);  for (; i>0; i--)		/* pad out bogon pointer */    (void)fputc(' ', stderr);  (void)fprintf(stderr, "^\n");}#include <ctype.h>/* check if the first word of a comment is the keyword */iskeycmnt(key,cmnt)  char key[], cmnt[];{  register char *c=cmnt+1;  char *s,t;  int r;  while (*c == ' ' || *c == '\t') c++;  s=c;  while (isalpha(*c)) c++;  t=*c; *c=NULL;  r=nstrcmp(key, s);  *c=t;  return (r==0);}/* my lex replacement code */#define iseol(c) ((c)=='\n')FILE *yyin = {stdin};#define input() fgetc(yyin)#define unputc(c) ungetc(c, yyin)yyinput() {return (input());}yyunputc(c) char c; {return (unputc(c));}#define MAXTOKEN 500char linebuf[MAXTOKEN*10];	/* input line buffer */char *eline;			/* end of input line */char *yytext;			/* start of last 'token' */int eollast = True;		/* say a \n last */int yylineno=1;			/* line number */int yyleng;			/* length of the last token (NUM only) */yylex(){  char *c;  if (lldebug)    fprintf(stderr,"Entering yylex, justtokens=%d\n", justtokens);  if (eollast && !restofline) {    yytext = linebuf;    eollast = False;  } else    yytext = eline;  c = yytext;  for(;;) {    if (restofline) {      if (!eollast) {	while (! iseol(*c))	  *++c=input();	unputc(*c);	*c = NULL;	eline = c;      }      return (RESTOFLINE);    }    *c=input();    if (*c == EOF)      return (0);    if (iseol(*c)) {      *c = NULL;      eollast++;      yylineno++;       return ('\n');    }    if (isspace(*c)) {      do *++c=input(); while (isspace(*c) && (! iseol(*c))) ;      unputc(*c);      *c = NULL;      yytext = c;      continue;			/* just ignore the spaces */    }    if (*c == '"')      goto special;    if (justtokens) {      do *++c=input(); while (! isspace(*c) && ! iseol(*c) && *c != '"') ;      unputc(*c);      *c = NULL;      eline = c;      yylval.c = yytext;      if (justtokens>0)	return (TOKEN);      /* else, check for a keyword */      return (lookkey(yytext));    }    if (isdigit(*c)) {      for (yyleng=0; isdigit(*c) ; yyleng++) 	*++c = input();      unputc(*c);      *c = NULL;      eline = c;      yylval.c = yytext;      return (NUM);    }    if (*c == '*') {      *++c = input();      if (*c == '.') {		/* an funny name? */	*++c = input();	if (! isalpha(*c)) {	  unputc(*c--);	  unputc(*c--);		/* put the '.' back also */	}      } else {	unputc(*c--);      }    }    if (isalpha(*c)) {      do *++c = input(); while (isalnum(*c) || *c=='.' || *c=='-') ;      if (*c == ':') {		/* maybe a TXT keyword? */	int r;	*++c = NULL;	if ((r=lookkey(yytext)) != TOKEN) {	  eline = c;		/* yes */	  return (r);	}	c--;			/* no, unput ':', test for other keywords */      }      unputc(*c);      *c = NULL;      eline = c;      yylval.c = yytext;      return (lookup(yytext));    }    if (*c == '$') {      do *++c = input(); while (isalnum(*c)) ;      unputc(*c);      *c = NULL;      eline = c;      if (nstrcmp(yytext, "$include") == 0)	return (INCLUDE);      if (nstrcmp(yytext, "$origin") == 0)	return (ORIGIN);      return (TOKEN);    }  special:    eline = c;    *++eline = NULL;    return (*c);  }}#define lc(c) (isupper(c)?tolower(c):(c))/* case insensitive string compare (ala. strcmp(3)) */nstrcmp(str1, str2)  char str1[], str2[];{  register char *s, *t;  for (s=str1, t=str2; *s!=NULL && *t!=NULL && lc(*s)==lc(*t); s++, t++) ;  if (*s==NULL)    if (*t==NULL) {      return (0);    } else {      return (-1);    }  return (1);}/* symbol tables */#define SYM struct symSYM {  char *key;  int token;};SYM dict[] = {  {"a", A},  {"cname", CNAME},  {"gid", GID},  {"hinfo", HINFO},  {"in", IN},  {"mb", MB},  {"mg", MG},  {"mr", MR},  {"mx", MX},  {"ns", NS},  {"null", NULLRR},  {"ptr", PTR},  {"rp", RP},  {"soa", SOA},  {"txt", TXT},  {"afsdb", AFSDB},  {"uid", UID},  {"uinfo", UINFO},  {"unspec", UNSPEC},  {"wks", WKS}};#define DICTSIZE (sizeof(dict)/sizeof(SYM))SYM tdict[] = {  {"campus:", CAMPUS},  {"location:", LOCATION},  {"mailaddr:", MADDR},  {"name:", PNAME},  {"officeaddr:", OADDR},  {"extension:", EXTENSION},  {"officephone:", OPHONE},  {"organization:", ORGANIZATION},  {"owner:", OWNER},  {"person:", PERSON},  {"room:", ROOM},};#define TDICTSIZE (sizeof(tdict)/sizeof(SYM))int dict_compare(sym1, sym2)  SYM *sym1, *sym2;{  return strcmp(sym1->key, sym2->key);}#ifdef NOPEchar *bsearch(key, base, nel, keysize, compar)  char *key, *base;  unsigned nel;  int keysize;  int (*compar)();{  register char *b;  register i=nel;  for (b=base, i=0; i<=nel; i++, b+=keysize)    if ((*compar)(key, b) == 0)      return (b);}#endif NOPElookkey(t)  char t[];{  SYM *d, e;  char name[MAXNAME];  register char *f, *n;  /* lowercase input */  for (f=t, n=name; *f!=NULL; f++, n++)    *n = (isupper(*f))?tolower(*f):*f;  *n=NULL;      e.key = name;  d = (SYM *)bsearch((char *)(&e), (char *)tdict, TDICTSIZE,		     sizeof(SYM), dict_compare);  if (d != (SYM *)NULL)    return (d->token);  return (TOKEN);}lookup(t)  char t[];{  SYM *d, e;  char name[MAXNAME];  register char *f, *n;  /* lowercase input */  for (f=t, n=name; *f!=NULL; f++, n++)    *n = (isupper(*f))?tolower(*f):*f;  *n=NULL;      e.key = name;  			 /* key          base   nel */  d = (SYM *)bsearch((char *)(&e), (char *)dict, DICTSIZE,		     /* sizeof(*key)     commpar */		     sizeof(SYM), dict_compare);  if (d != (SYM *)NULL)    return(d->token);  d = (SYM *)bsearch((char *)(&e), (char *)tdict, TDICTSIZE,		     sizeof(SYM), dict_compare);  if (d != (SYM *)NULL)    return(d->token);  return(NAME);}stophere(){return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -