
/* 
 * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 
 */

/* Updated: David Caplan, <dac@tresys.com>
 *
 * 	Added conditional policy language extensions
 *
 *          Jason Tang    <jtang@tresys.com>
 *
 *	Added support for binary policy modules
 *
 * Copyright (C) 2003-5 Tresys Technology, LLC
 *	This program is free software; you can redistribute it and/or modify
 *  	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, version 2.
 */

/* FLASK */

%{
#include <sys/types.h>
#include <limits.h>
#include <stdint.h>
#include <string.h>

typedef int (* require_func_t)(void);

#ifdef ANDROID
#include "policy_parse.h"
#else
#include "y.tab.h"
#endif

static char linebuf[2][255];
static unsigned int lno = 0;
int yywarn(const char *msg);

void set_source_file(const char *name);

char source_file[PATH_MAX];
unsigned long source_lineno = 1;

unsigned long policydb_lineno = 1;

unsigned int policydb_errors = 0;
%}

%option noinput nounput noyywrap

%array
letter  [A-Za-z]
digit   [0-9]
alnum   [a-zA-Z0-9]
hexval	[0-9A-Fa-f]

%%
\n.*				{ strncpy(linebuf[lno], yytext+1, 255);
                                  linebuf[lno][254] = 0;
                                  lno = 1 - lno; 
                                  policydb_lineno++;
				  source_lineno++;
                                  yyless(1); }
CLONE |
clone				{ return(CLONE); }
COMMON |
common				{ return(COMMON); }
CLASS |
class				{ return(CLASS); }
CONSTRAIN |
constrain			{ return(CONSTRAIN); }
VALIDATETRANS |
validatetrans			{ return(VALIDATETRANS); }
INHERITS |
inherits			{ return(INHERITS); }
SID |
sid				{ return(SID); }
ROLE |
role				{ return(ROLE); }
ROLES |
roles				{ return(ROLES); }
ROLEATTRIBUTE |
roleattribute			{ return(ROLEATTRIBUTE);}
ATTRIBUTE_ROLE |
attribute_role			{ return(ATTRIBUTE_ROLE);}
TYPES |
types				{ return(TYPES); }
TYPEALIAS |
typealias			{ return(TYPEALIAS); }
TYPEATTRIBUTE |
typeattribute			{ return(TYPEATTRIBUTE); }
TYPEBOUNDS |
typebounds			{ return(TYPEBOUNDS); }
TYPE |
type				{ return(TYPE); }
BOOL |
bool                            { return(BOOL); }
TUNABLE |
tunable				{ return(TUNABLE); }
IF |
if				{ return(IF); }
ELSE |
else				{ return(ELSE); }
ALIAS |
alias				{ return(ALIAS); }
ATTRIBUTE |
attribute			{ return(ATTRIBUTE); }
TYPE_TRANSITION |
type_transition			{ return(TYPE_TRANSITION); }
TYPE_MEMBER |
type_member			{ return(TYPE_MEMBER); }
TYPE_CHANGE |
type_change			{ return(TYPE_CHANGE); }
ROLE_TRANSITION |
role_transition			{ return(ROLE_TRANSITION); }
RANGE_TRANSITION |
range_transition		{ return(RANGE_TRANSITION); }
SENSITIVITY |
sensitivity			{ return(SENSITIVITY); }
DOMINANCE |
dominance			{ return(DOMINANCE); }
CATEGORY |
category			{ return(CATEGORY); }
LEVEL |
level				{ return(LEVEL); }
RANGE |
range				{ return(RANGE); }
MLSCONSTRAIN |
mlsconstrain			{ return(MLSCONSTRAIN); }
MLSVALIDATETRANS |
mlsvalidatetrans		{ return(MLSVALIDATETRANS); }
USER |
user				{ return(USER); }
NEVERALLOW |
neverallow		        { return(NEVERALLOW); }
ALLOW |
allow			        { return(ALLOW); }
AUDITALLOW |
auditallow		        { return(AUDITALLOW); }
AUDITDENY |
auditdeny		        { return(AUDITDENY); }
DONTAUDIT |
dontaudit                       { return(DONTAUDIT); }
SOURCE |
source			        { return(SOURCE); }
TARGET |
target			        { return(TARGET); }
SAMEUSER |
sameuser			{ return(SAMEUSER);}
module|MODULE                   { return(MODULE); }
require|REQUIRE                 { return(REQUIRE); }
optional|OPTIONAL               { return(OPTIONAL); }
OR |
or     			        { return(OR);}
AND |
and				{ return(AND);}
NOT |
not				{ return(NOT);}
xor |
XOR                             { return(XOR); }
eq |
EQ				{ return(EQUALS);}
true |
TRUE                            { return(CTRUE); } 
false |
FALSE                           { return(CFALSE); } 
dom |
DOM				{ return(DOM);}
domby |
DOMBY				{ return(DOMBY);}
INCOMP |
incomp				{ return(INCOMP);}
fscon |
FSCON                           { return(FSCON);}
portcon |
PORTCON				{ return(PORTCON);}
netifcon |                     
NETIFCON			{ return(NETIFCON);}
nodecon |                     
NODECON				{ return(NODECON);}
pirqcon |
PIRQCON  		        { return(PIRQCON);}
iomemcon |
IOMEMCON            		{ return(IOMEMCON);}
ioportcon |
IOPORTCON           		{ return(IOPORTCON);}
pcidevicecon |
PCIDEVICECON           		{ return(PCIDEVICECON);}
fs_use_xattr |
FS_USE_XATTR			{ return(FSUSEXATTR);}
fs_use_task |
FS_USE_TASK                     { return(FSUSETASK);}
fs_use_trans |
FS_USE_TRANS                    { return(FSUSETRANS);}
genfscon |
GENFSCON                        { return(GENFSCON);}
r1 |
R1				{ return(R1); }
r2 |
R2				{ return(R2); }
r3 |
R3				{ return(R3); }
u1 |
U1				{ return(U1); }
u2 |
U2				{ return(U2); }
u3 |
U3				{ return(U3); }
t1 |
T1				{ return(T1); }
t2 |
T2				{ return(T2); }
t3 |
T3				{ return(T3); }
l1 |
L1				{ return(L1); }
l2 |
L2				{ return(L2); }
h1 |
H1				{ return(H1); }
h2 |
H2				{ return(H2); }
policycap |
POLICYCAP			{ return(POLICYCAP); }
permissive |
PERMISSIVE			{ return(PERMISSIVE); }
default_user |
DEFAULT_USER			{ return(DEFAULT_USER); }
default_role |
DEFAULT_ROLE			{ return(DEFAULT_ROLE); }
default_type |
DEFAULT_TYPE			{ return(DEFAULT_TYPE); }
default_range |
DEFAULT_RANGE			{ return(DEFAULT_RANGE); }
low-high |
LOW-HIGH			{ return(LOW_HIGH); }
high |
HIGH				{ return(HIGH); }
low |
LOW				{ return(LOW); }
"/"({alnum}|[_\.\-/])*	        { return(PATH); }
\"({alnum}|[_\.\-\+\~\: ])+\"	{ return(FILENAME); }
{letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))*	{ return(IDENTIFIER); }
{digit}+|0x{hexval}+            { return(NUMBER); }
{alnum}*{letter}{alnum}*        { return(FILESYSTEM); }
{digit}{1,3}(\.{digit}{1,3}){3}    { return(IPV4_ADDR); }
{hexval}{0,4}":"{hexval}{0,4}":"({hexval}|[:.])*  { return(IPV6_ADDR); }
{digit}+(\.({alnum}|[_.])*)?    { return(VERSION_IDENTIFIER); }
#line[ ]1[ ]\"[^\n]*\"		{ set_source_file(yytext+9); }
#line[ ]{digit}+	        { source_lineno = atoi(yytext+6)-1; }
#[^\n]*                         { /* delete comments */ }
[ \t\f]+			{ /* delete whitespace */ }
"==" 				{ return(EQUALS); }
"!="				{ return (NOTEQUAL); }
"&&"				{ return (AND); }
"||"				{ return (OR); }
"!"				{ return (NOT); }
"^"                             { return (XOR); }
"," |
":" |
";" |
"(" | 
")" |
"{" | 
"}" |
"[" |
"-" |
"." |
"]" |
"~" |
"*"				{ return(yytext[0]); } 
.                               { yywarn("unrecognized character");}
%%
int yyerror(const char *msg)
{
	if (source_file[0])
		fprintf(stderr, "%s:%ld:",
			source_file, source_lineno);
	else
		fprintf(stderr, "(unknown source)::");
	fprintf(stderr, "ERROR '%s' at token '%s' on line %ld:\n%s\n%s\n",
			msg,
			yytext,
			policydb_lineno,
			linebuf[0], linebuf[1]);
	policydb_errors++;
	return -1;
}

int yywarn(const char *msg)
{
	if (source_file[0])
		fprintf(stderr, "%s:%ld:",
			source_file, source_lineno);
	else
		fprintf(stderr, "(unknown source)::");
	fprintf(stderr, "WARNING '%s' at token '%s' on line %ld:\n%s\n%s\n",
			msg,
			yytext,
			policydb_lineno,
			linebuf[0], linebuf[1]);
	return 0;
}

void set_source_file(const char *name)
{
	source_lineno = 1;
	strncpy(source_file, name, sizeof(source_file)-1); 
	source_file[sizeof(source_file)-1] = '\0';
	if (strlen(source_file) && source_file[strlen(source_file)-1] == '"')
		source_file[strlen(source_file)-1] = '\0';
}
