%{
#if !defined(lint) && !defined(__INSIGHT__)
static char sos__rcsid[] = "parse.y,v 1.1.1.1 1995/06/16 21:10:47 seth Exp";
static char sos__copyright[] = "Copyright (c) 1994, 1995 SOS Corporation";
static char sos__contact[] = "SOS Corporation <sos-info@soscorp.com> +1 800 SOS UNIX";
#endif /* not lint */

/*
 * ++Copyright Released Product++
 *
 * Copyright (c) 1994, 1995 Sources of Supply Corporation ("SOS").
 * All rights reserved.
 *
 * The SOS Released Product License Agreement specifies the terms and
 * conditions for redistribution.  You may find the License Agreement
 * in the file LICENSE.
 *
 * SOS Corporation
 * 461 5th Ave.; 16th floor
 * New York, NY 10017
 *
 * +1 800 SOS UNIX
 * <sos-info@soscorp.com>
 *
 * --Copyright Released Product--
 */

/*
 * Do normal YACC things (convert token stream into internal form)
 */

#include "interface.h"
#include "readconf.h"
extern char *yytext;
extern char **curfile;

struct FirstLevel_t ANY = { "ANY", (dict_h)-2 };

int newline = 1;

%}
%union {
  char *strtype;
  dict_h dict;
  struct FirstLevel_t *first;
  struct element_t *elem;
  struct timeinfo_t *time;
  struct dateinfo_t *date;
  struct addrinfo_t *addr;
  struct servinfo_t *serv;
  struct groupinfo_t *group;
  struct userinfo_t *user;
  unsigned char day_t:7;
  unsigned int hour_t:24;
  unsigned long ulong;
  unsigned char uchar;
  int itype;
  char SYM;
}

%token <strtype> _QuotedString _String
%token <itype> _Number
%token <SYM> _Colon _Leftp _Rightp
%token <SYM> _Delim _Deref _Dot _Plus _Minus _Slash _Equal _EOL _MARK _BOF
%token <SYM> _Mon _Tue _Wed _Thu _Fri _Sat _Sun
%token <SYM> _ERROR

%type <strtype>	variable metatime metadate metaaddr metaserv metagroup
%type <dict>	timespecs timelist datespecs datelist addrspecs addrlist 
%type <dict>	servspecs servlist groupspecs grouplist userspecs
%type <first>	timeline dateline addrline servline groupline
%type <elem>	timeelem abstimeelem dateelem absdateelem addrelem absaddrelem
%type <elem>	servelem absservelem groupelem absgroupelem
%type <time>	directtime timeval
%type <date>	directdate dateval
%type <addr>	directaddr addrval
%type <serv>	directserv servval
%type <group>	directgroup groupval
%type <user>	userline
%type <day_t>	daylist days
%type <hour_t>	hourlist hours
%type <ulong>	quad
%type <uchar>	byte
%type <itype>	service day hour number
%type <strtype>	auth passwd GCOS contact responsible comment text string
%type <itype>	ena creatdate moddate expiredate month dayofmonth year
%type <SYM>	file bof marks eateol eols

%start file
%expect 1
%%

file		:  bof allocatemarks timespecs marks datespecs marks addrspecs marks servspecs marks groupspecs marks userspecs
		;

bof		:  _BOF eateol
		|  bof _BOF eateol
		|  eateol
		;

eateol		:  eols {}
		|  /* naught */ {}
		;

/***********************************************************************/
/* Info to define times */

timespecs	:  timeline
			{
			  $$ = TimeTbl;

			  if (ht_insert_uniq($$,$1,NULL) == DICT_ERR)
			    {

			      sprintf(bs_auth_extended,"%s appears more than once (%d)",
				      $1->key,dict_errno);
			      return(AUTH_ERROR);
			    }
			}
		|  timespecs timeline
			{
			  $$ = $1;
			  TimeSize.ht_table_entries++;
			  if (ht_insert_uniq($1,$2,NULL) == DICT_ERR)
			    {

			      sprintf(bs_auth_extended,"%s appears more than once (%d)",
				      (char *)($1),dict_errno);
			      return(AUTH_ERROR);
			    }
			}
		;

timeline	:  variable _Equal timelist eols
			{	/* Store times information into hash table */
			  $$ = (struct FirstLevel_t *)malloc(sizeof(struct FirstLevel_t));
			  $$->key = $1; $$->info = $3;
			}
		;

timelist	:  timeelem
			{
			  $$ = dll_create(NULL, NULL, DICT_UNORDERED, NULL);
			  dll_insert($$,$1);
			}
		|  timelist _Delim timeelem
			{
			  $$ = $1;
			  dll_insert($$,$3);
			}
		;

/* The actual elements */
timeelem	:  abstimeelem
			{ $$ = $1; $$->neg = 0; }
		|  _Plus abstimeelem
			{ $$ = $2; $$->neg = 0; }
		|  _Minus abstimeelem
			{ $$ = $2; $$->neg = 1; }

/* The absolute value of the elements--take care of pos/neg higher */
abstimeelem	:  metatime
			{
			  $$ = (struct element_t *)malloc(sizeof(struct element_t));
			  $$->meta = 1;
			  $$->ptr.meta = $1;
			}
		|  directtime
			{
			  $$ = (struct element_t *)malloc(sizeof(struct element_t));
			  $$->meta = 0;
			  $$->ptr.time = $1;
			}
		;

/* Indirect time */
metatime	:  _Deref variable
			{	/* Make sure we have seen this before... */
			  if (!ht_search(TimeTbl,$2))
			    {
			      sprintf(bs_auth_extended,"Metavariable %s has not appeared yet",$2);
			      return(AUTH_ERROR);
			    }
			  $$ = $2;
			}
		;

/* What a timeset looks like */
directtime	:  _Leftp timeval _Rightp
			{ $$ = $2; }
		;

/* list of days and hours */
timeval		:  daylist _Slash hourlist
			{
			  $$ = (struct timeinfo_t *)malloc(sizeof(struct timeinfo_t));
			  $$->day = $1;
			  $$->hour = $3;
			}
		;

/* one or more days or ranges of days */
daylist		:  days
			{ $$ = $1; }
		|  daylist _Delim days
			{ $$ = $1 | $3; }
		;

/* one day or day range */
days		:  day
			{
			  int tmp;
			  tmp = days2bit($1,-1);
			  $$ = tmp;
			  if (tmp == AUTH_ERROR)
			    return(AUTH_ERROR);
			}
		|  day _Minus day
			{
			  int tmp;
			  tmp = days2bit($1,$3);
			  $$ = tmp;
			  if (tmp == AUTH_ERROR)
			    return(AUTH_ERROR);
			}
		;

/* Day of week; Numbers are from struct tm */
day		:  _Mon { $$ = 1 }
		|  _Tue { $$ = 2 }
		|  _Wed { $$ = 3 }
		|  _Thu { $$ = 4 }
		|  _Fri { $$ = 5 }
		|  _Sat { $$ = 6 }
		|  _Sun { $$ = 0 }
		;

/* One or more hours or hour ranges */
hourlist	:  hours
			{ $$ = $1; }
		|  hourlist _Delim hours
			{ $$ = $1 | $3; }
		;

/* One hour or hour range */
hours		:  hour
			{
			  int tmp;
			  tmp = hour2bit($1,-1);
			  $$ = tmp;
			  if (tmp == AUTH_ERROR)
			    return(AUTH_ERROR);
			}
		|  hour _Minus hour
			{
			  int tmp;
			  tmp = hour2bit($1,$3);
			  $$ = tmp;
			  if (tmp == AUTH_ERROR)
			    return(AUTH_ERROR);
			}
		;

/* One hour */
hour		:  number
			{ $$ = $1; }
		;


/***********************************************************************/
/* Info to define dates */

datespecs	:  dateline
			{
			  $$ = DateTbl;
			  if (ht_insert_uniq($$,$1,NULL) == DICT_ERR)
			    {

			      sprintf(bs_auth_extended,"%s appears more than once (%d)",
				      (char *)($1),dict_errno);
			      return(AUTH_ERROR);
			    }
			}
		|  datespecs dateline
			{
			  $$ = $1;
			  DateSize.ht_table_entries++;
			  if (ht_insert_uniq($1,$2,NULL) == DICT_ERR)
			    {

			      sprintf(bs_auth_extended,"%s appears more than once (%d)",
				      (char *)($1),dict_errno);
			      return(AUTH_ERROR);
			    }
			}
		;

dateline	:  variable _Equal datelist eols
			{	/* Store dates information into hash table */
			  $$ = (struct FirstLevel_t *)malloc(sizeof(struct FirstLevel_t));
			  $$->key = $1; $$->info = $3;
			}
		;

datelist	:  dateelem
			{
			  $$ = dll_create(NULL, NULL, DICT_UNORDERED, NULL);
			  dll_insert($$,$1);
			}
		|  datelist _Delim dateelem
			{
			  $$ = $1;
			  dll_insert($$,$3);
			}
		;

/* The actual elements */
dateelem	:  absdateelem
			{ $$ = $1; $$->neg = 0; }
		|  _Plus absdateelem
			{ $$ = $2; $$->neg = 0; }
		|  _Minus absdateelem
			{ $$ = $2; $$->neg = 1; }

/* The absolute value of the elements--take care of pos/neg higher */
absdateelem	:  metadate
			{
			  $$ = (struct element_t *)malloc(sizeof(struct element_t));
			  $$->meta = 1;
			  $$->ptr.meta = $1;
			}
		|  directdate
			{
			  $$ = (struct element_t *)malloc(sizeof(struct element_t));
			  $$->meta = 0;
			  $$->ptr.date = $1;
			}
		;

/* Indirect date */
metadate	:  _Deref variable
			{	/* Make sure we have seen this before... */
			  if (!ht_search(DateTbl,$2))
			    {
			      sprintf(bs_auth_extended,"Metavariable %s has not appeared yet",$2);
			      return(AUTH_ERROR);
			    }
			  $$ = $2;
			}
		;

/* What a dateset looks like */
directdate	:  _Leftp dateval _Rightp
			{ $$ = $2; }
		;

/* list of days and hours */
dateval		:  month _Slash dayofmonth _Slash year
			{
			  struct tm utime;
			  time_t clock;

			  memset((char *)&utime,0,sizeof(utime));

			  utime.tm_mon = $1-1;
			  utime.tm_mday = $3;
			  utime.tm_year = $5 - 1900;
			  utime.tm_zone = "GMT";
			  clock = mktime(&utime);

			  $$ = (struct dateinfo_t *)malloc(sizeof(struct dateinfo_t));
			  $$->days = clock / 86400; /* Compute days since epoch */

			  if (bs_debug) fprintf(stderr," Date parsed to %d %d\n",clock,$$->days);

			}
		;

month		:  number
			{
			  if ($1 < 1 || $1 > 12)
			    {
			      sprintf(bs_auth_extended,"%d is an invalid month (1-12)",$1);
			      return(AUTH_ERROR);
			    }
			}
		;

dayofmonth	:  number
			{
			  if ($1 < 1 || $1 > 31)
			    {
			      sprintf(bs_auth_extended,"%d is an invalid day (1-31)",$1);
			      return(AUTH_ERROR);
			    }
			}
		;

year		:  number
			{
			  if ($1 < 1990 || $1 > 2020)
			    {
			      sprintf(bs_auth_extended,"%d is an invalid year (1990-2020)",$1);
			      return(AUTH_ERROR);
			    }
			}
		;


/***********************************************************************/
/* Info to define addresses */

addrspecs	:  addrline
			{
			  $$ = AddrTbl;
			  if (ht_insert_uniq($$,$1,NULL) == DICT_ERR)
			    {

			      sprintf(bs_auth_extended,"%s appears more than once (%d)",
				      (char *)($1),dict_errno);
			      return(AUTH_ERROR);
			    }
			}
		|  addrspecs addrline
			{
			  $$ = $1;
			  AddrSize.ht_table_entries++;
			  if (ht_insert_uniq($1,$2,NULL) == DICT_ERR)
			    {

			      sprintf(bs_auth_extended,"%s appears more than once (%d)",
				      (char *)($1),dict_errno);
			      return(AUTH_ERROR);
			    }
			}
		;



addrline	:  variable _Equal addrlist eols
			{	/* Store addrs information into hash table */
			  $$ = (struct FirstLevel_t *)malloc(sizeof(struct FirstLevel_t));
			  $$->key = $1; $$->info = $3;
			}
		;

addrlist	:  addrelem
			{
			  $$ = dll_create(NULL, NULL, DICT_UNORDERED, NULL);
			  dll_insert($$,$1);
			}
		|  addrlist _Delim addrelem
			{
			  $$ = $1;
			  dll_insert($$,$3);
			}
		;

/* The actual elements */
addrelem	:  absaddrelem
			{ $$ = $1; $$->neg = 0; }
		|  _Plus absaddrelem
			{ $$ = $2; $$->neg = 0; }
		|  _Minus absaddrelem
			{ $$ = $2; $$->neg = 1; }

/* The absolute value of the elements--take care of pos/neg higher */
absaddrelem	:  metaaddr
			{
			  $$ = (struct element_t *)malloc(sizeof(struct element_t));
			  $$->meta = 1;
			  $$->ptr.meta = $1;
			}
		|  directaddr
			{
			  $$ = (struct element_t *)malloc(sizeof(struct element_t));
			  $$->meta = 0;
			  $$->ptr.addr = $1;
			}
		;

/* Indirect addr */
metaaddr	:  _Deref variable
			{	/* Make sure we have seen this before... */
			  if (!ht_search(AddrTbl,$2))
			    {
			      sprintf(bs_auth_extended,"Metavariable %s has not appeared yet",$2);
			      return(AUTH_ERROR);
			    }
			  $$ = $2;
			}
		;

/* What a addrset looks like */
directaddr	:  _Leftp addrval _Rightp
			{ $$ = $2; }
		;

/* Address, mask pair */
addrval		:  quad _Delim quad
			{
			  $$ = (struct addrinfo_t *)malloc(sizeof(struct addrinfo_t));
			  $$->Primary.s_addr = ntohl($1);
			  $$->Mask.s_addr = ntohl($3);
			}
		;

/* XXX - Assuming S_addr fits in an u_long */
quad		:  byte _Dot byte _Dot byte _Dot byte
			{ $$ = ($1<<24) + ($3<<16) + ($5<<8) + $7; }
		;

byte		: number
			{
			  $$ = $1;
			  if ($$ > 255)	
			    {
			      sprintf(bs_auth_extended,"Bytes in IP address are [0-255] not %d\n",$$);
			      return(AUTH_ERROR);
			    }
			}
		;

/***********************************************************************/
/* Service info */

servspecs	:  servline
			{
			  $$ = ServTbl;
			  if (ht_insert_uniq($$,$1,NULL) == DICT_ERR)
			    {

			      sprintf(bs_auth_extended,"%s appears more than once (%d)",
				      (char *)($1),dict_errno);
			      return(AUTH_ERROR);
			    }
			}
		|  servspecs servline
			{
			  $$ = $1;
			  ServSize.ht_table_entries++;
			  if (ht_insert_uniq($1,$2,NULL) == DICT_ERR)
			    {

			      sprintf(bs_auth_extended,"%s appears more than once (%d)",
				      (char *)($1),dict_errno);
			      return(AUTH_ERROR);
			    }
			}
		;

servline	:  variable _Equal servlist eols
			{	/* Store servs information into hash table */
			  $$ = (struct FirstLevel_t *)malloc(sizeof(struct FirstLevel_t));
			  $$->key = $1; $$->info = $3;
			}
		;

servlist	:  servelem
			{
			  $$ = dll_create(NULL, NULL, DICT_UNORDERED, NULL);
			  dll_insert($$,$1);
			}
		|  servlist _Delim servelem
			{
			  $$ = $1;
			  dll_insert($$,$3);
			}
		;

/* The actual elements */
servelem	:  absservelem
			{ $$ = $1; $$->neg = 0; }
		|  _Plus absservelem
			{ $$ = $2; $$->neg = 0; }
		|  _Minus absservelem
			{ $$ = $2; $$->neg = 1; }

/* The absolute value of the elements--take care of pos/neg higher */
absservelem	:  metaserv
			{
			  $$ = (struct element_t *)malloc(sizeof(struct element_t));
			  $$->meta = 1;
			  $$->ptr.meta = $1;
			}
		|  directserv
			{
			  $$ = (struct element_t *)malloc(sizeof(struct element_t));
			  $$->meta = 0;
			  $$->ptr.serv = $1;
			}
		;

/* Indirect serv */
metaserv	:  _Deref variable
			{	/* Make sure we have seen this before... */
			  if (!ht_search(ServTbl,$2))
			    {
			      sprintf(bs_auth_extended,"Metavariable %s has not appeared yet",$2);
			      return(AUTH_ERROR);
			    }
			  $$ = $2;
			}
		;

/* What a servset looks like */
directserv	:  _Leftp servval _Rightp
			{ $$ = $2; }
		|  servval
			{ $$ = $1; }
		;

servval		:  service
			{
			  $$ = (struct servinfo_t *)malloc(sizeof(struct servinfo_t));
			  $$->service = $1;
			}
		;

service		:  string
			{
			  struct servent *x;

			  if (!(x=getservbyname($1,"tcp")))
			    {
			      sprintf(bs_auth_extended,"Service %s is unknown",$1);
			      return(AUTH_ERROR);
			    }

			  /* Getservbyname returns port in network order */
			  $$ = ntohs(x->s_port);
			  free($1);
			}
		|  number
			{ $$ = $1; }
		;

/***********************************************************************/
/* Define groups */


groupspecs	:  groupline
			{
			  $$ = GroupTbl;
			  if (ht_insert_uniq($$,$1,NULL) == DICT_ERR)
			    {

			      sprintf(bs_auth_extended,"%s appears more than once (%d)",
				      (char *)($1),dict_errno);
			      return(AUTH_ERROR);
			    }
			}
		|  groupspecs groupline
			{
			  $$ = $1;
			  GroupSize.ht_table_entries++;
			  if (ht_insert_uniq($1,$2,NULL) == DICT_ERR)
			    {

			      sprintf(bs_auth_extended,"%s appears more than once (%d)",
				      (char *)($1),dict_errno);
			      return(AUTH_ERROR);
			    }
			}
		;

groupline	:  variable _Equal grouplist eols
			{	/* Store groups information into hash table */
			  $$ = (struct FirstLevel_t *)malloc(sizeof(struct FirstLevel_t));
			  $$->key = $1; $$->info = $3;
			}
		;

grouplist	:  groupelem
			{
			  $$ = dll_create(NULL, NULL, DICT_UNORDERED, NULL);
			  dll_insert($$,$1);
			}
		|  grouplist _Delim groupelem
			{
			  $$ = $1;
			  dll_insert($$,$3);
			}
		;

/* The actual elements */
groupelem	:  absgroupelem
			{ $$ = $1; $$->neg = 0; }
		|  _Plus absgroupelem
			{ $$ = $2; $$->neg = 0; }
		|  _Minus absgroupelem
			{ $$ = $2; $$->neg = 1; }

/* The absolute value of the elements--take care of pos/neg higher */
absgroupelem	:  metagroup
			{
			  $$ = (struct element_t *)malloc(sizeof(struct element_t));
			  $$->meta = 1;
			  $$->ptr.meta = $1;
			}
		|  directgroup
			{
			  $$ = (struct element_t *)malloc(sizeof(struct element_t));
			  $$->meta = 0;
			  $$->ptr.group = $1;
			}
		;

/* Indirect group */
metagroup	:  _Deref variable
			{	/* Make sure we have seen this before... */
			  if (!ht_search(GroupTbl,$2))
			    {
			      sprintf(bs_auth_extended,"Metavariable %s has not appeared yet",$2);
			      return(AUTH_ERROR);
			    }
			  $$ = $2;
			}
		;

directgroup	:  _Leftp groupval _Rightp
			{ $$ = $2; }
		;


/* What a groupset looks like */
groupval	:  metatime _Delim metadate _Delim metaaddr _Delim metaserv _Delim metaaddr _Delim metaserv
			{
			  $$ = (struct groupinfo_t *)malloc(sizeof(struct groupinfo_t));
			  $$->metatime = $1;
			  $$->metadate = $3;
			  $$->srcmetaaddr = $5;
			  $$->srcmetaserv = $7;
			  $$->dstmetaaddr = $9;
			  $$->dstmetaserv = $11;
			}
		;

/***********************************************************************/
/* User info */

userspecs	:  userline
			{
			  UserTbl = ht_create(mystrcmp,mykeycmp,DICT_UNIQUE_KEYS,NULL,&UserSize);
			  UserSize.ht_table_entries = 1;
			  $$ = UserTbl;
			  if (ht_insert_uniq($$,$1,NULL) == DICT_ERR)
			    {

			      sprintf(bs_auth_extended,"%s appears more than once (%d)",
				      (char *)($1),dict_errno);
			      return(AUTH_ERROR);
			    }
			}
		|  userspecs userline
			{
			  $$ = $1;
			  UserSize.ht_table_entries++;
			  if (ht_insert_uniq($1,$2,NULL) == DICT_ERR)
			    {

			      sprintf(bs_auth_extended,"%s appears more than once (%d)",
				      (char *)($1),dict_errno);
			      return(AUTH_ERROR);
			    }
			}
		;

userline	:  variable _Equal ena _Colon auth _Colon passwd _Colon metagroup _Colon creatdate _Colon moddate _Colon expiredate _Colon contact _Colon responsible _Colon GCOS _Colon comment eols
			{	/* Store users information into hash table */
			  $$ = (struct userinfo_t *)malloc(sizeof(struct userinfo_t));
			  $$->user = $1;
			  $$->ena = $3;
			  $$->auth = $5;
			  $$->acode = $7;
			  $$->group = $9;
			  $$->create = $11;
			  $$->last = $13;
			  $$->expire = $15;
			  $$->contact = $17;
			  $$->responsible = $19;
			  $$->GCOS = $21;
			  $$->comment = $23;
			}
		;

ena		:  number { $$=$1; }
		|  /* Naught */ { $$=0; }
		;

auth		:  text { $$=$1; }
		;

passwd		:  string { $$=$1; }
		|  /* Naught */ { $$=""; }
		;

GCOS		:  string { $$=$1; }
		|  /* Naught */ { $$=""; }
		;

creatdate	:  number { $$=$1; }
		|  /* Naught */ { $$=0; }
		;

moddate		:  number { $$=$1; }
		|  /* Naught */ { $$=0; }
		;

expiredate	:  number { $$=$1; }
		|  /* Naught */ { $$=0; }
		;

contact		:  string { $$=$1; }
		|  /* Naught */ { $$=""; }
		;

responsible	:  string { $$=$1; }
		|  /* Naught */ { $$=""; }
		;

comment		:  string { $$=$1; }
		|  /* Naught */ { $$=""; }
		;



/***********************************************************************/
/***********************************************************************/
/* Common rules */

variable	: _String { $$ = strdup(yytext); } ;
text		: _String { $$ = strdup(yytext); } ;
number		: _Number { $$ = (atoi(yytext)); } ;

string		: _String { $$ = strdup(yytext); }
		| _QuotedString { $$ = strdup(string_buf); }
		;

eols		:  _EOL { newline++; }
		|  eols _EOL { newline++; }
		;

marks		: _MARK eateol ;

allocatemarks	: marks
			{
			  TimeTbl = ht_create(mystrcmp,mykeycmp,DICT_UNIQUE_KEYS,NULL,&TimeSize);
			  TimeSize.ht_table_entries = 1;
			  if (ht_insert_uniq(TimeTbl,FIRSTANY,NULL) == DICT_ERR)
			    {
			      sprintf(bs_auth_extended,"Cannot add default entry ANY (%d)",
				      dict_errno);
			      return(AUTH_ERROR);
			    }

			  DateTbl = ht_create(mystrcmp,mykeycmp,DICT_UNIQUE_KEYS,NULL,&DateSize);
			  DateSize.ht_table_entries = 1;
			  if (ht_insert_uniq(DateTbl,FIRSTANY,NULL) == DICT_ERR)
			    {
			      sprintf(bs_auth_extended,"Cannot add default entry ANY (%d)",
				      dict_errno);
			      return(AUTH_ERROR);
			    }

			  AddrTbl = ht_create(mystrcmp,mykeycmp,DICT_UNIQUE_KEYS,NULL,&AddrSize);
			  AddrSize.ht_table_entries = 1;
			  if (ht_insert_uniq(AddrTbl,FIRSTANY,NULL) == DICT_ERR)
			    {
			      sprintf(bs_auth_extended,"Cannot add default entry ANY (%d)",
				      dict_errno);
			      return(AUTH_ERROR);
			    }

			  ServTbl = ht_create(mystrcmp,mykeycmp,DICT_UNIQUE_KEYS,NULL,&ServSize);
			  ServSize.ht_table_entries = 1;
			  if (ht_insert_uniq(ServTbl,FIRSTANY,NULL) == DICT_ERR)
			    {
			      sprintf(bs_auth_extended,"Cannot add default entry ANY (%d)",
				      dict_errno);
			      return(AUTH_ERROR);
			    }

			  GroupTbl = ht_create(mystrcmp,mykeycmp,DICT_UNIQUE_KEYS,NULL,&GroupSize);
			  GroupSize.ht_table_entries = 1;
			}

%%
yyerror (char *s)
{
  sprintf(bs_auth_extended,"Parse fail: %s in file %s line %d (near %s)",s,*curfile,newline,yytext);
  return(0);
}
