
/* 
 * 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);}
devicetreecon |
DEVICETREECON           	{ return(DEVICETREECON);}
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); }
\""/"[ !#-~]*\" 		{ return(QPATH); }
\"({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';
}
