%{
    #include "rss.h"
%}    

%token USERS LINE IDENTIFIER DESTINATIONS NUMBER DIRECT EXTRA USING
	SCRATCH PATH GETTYPATH MODEMGETTY LOGIN EMAIL PANICLOG LOGFILE
	EMAIL RETRY NOKILLS SHOWNUMS LOGIN CALL LOG ON DEFAULT OFF
	MODE CALLBACK DIALIN NODESTINATIONS DIALLOG

%%

input:
    MODE
    colon
    modetype

modetype:
    callback
    defaultlist
    destinationsection
    usersection
|
    dialin
    defaultlist
;

callback:
    CALLBACK
    {
	cb_mode = mode_callback;
    }
;

dialin:
    DIALIN
    {
	cb_mode = mode_dialin;
    }
;

defaultlist:
    defaults
    {
	checkdefaults();
    }
;

defaults:
    defaults 
    default
|
    default			/* at least one default (line) needed */
;

default:
    linesection
|
    scratchfile
|
    pathsection
|
    gettydefault
|
    modemgetty
|
    nokills
|
    retry
|
    shownums
|
    paniclog
|
    logfile
|
    diallogfile
|
    email
|
    login
|
    call
|
    logtype
|
    showextra
|
    showdirect
|
    nodestinations
|
    error
;

call:
    CALL
    {
	if (cb_mode != mode_callback)
	    yysemantic("'call' only valid for mode callback");
	call = 1;
    }
;
    
logtype:
    LOG
    colon
    logvalue
;

logvalue:
    on_off
    {
        log_type =
            $1 ?
                log_on
            :
                log_off
         ;
    }
|
    DEFAULT
    {
	log_type = log_default;
    }
|
    {
	expect = "log type (on, off, or default)";
    }
    error
;

on_off:
    ON
    {
	$$ = 1;
    }
|
    OFF
    {
	$$ = 0;
    }
;

login:
    login_keyword
    colon
    loginprog
;

login_keyword:
    LOGIN
    {
	if (cb_mode != mode_callback)
	    yysemantic("'login: ...' only valid for mode callback");
    }
;

loginprog:
    IDENTIFIER
    {
	login_program = xstrdup(yytext);
	expect = "default setting or 'users'";
    }
|
    {
	expect = "login programname";
    }
    error
;

email:
    EMAIL
    colon
    address
;

address:
    IDENTIFIER
    {
	email_address = xstrdup(yytext);
	expect = "default setting or 'users'";
    }
|
    {
	expect = "e-mail address";
    }
    error
;

diallogfile:
    DIALLOG
    colon
    diallog
;

diallog:
    IDENTIFIER
    {
	diallog_filename = xstrdup(yytext);
	expect = "default setting or 'users'";
    }
|
    {
	expect = "dial-logfilename";
    }
    error
;

logfile:
    LOGFILE
    colon
    log
;

log:
    IDENTIFIER
    {
	log_filename = xstrdup(yytext);
	expect = "default setting or 'users'";
    }
|
    {
	expect = "logfilename";
    }
    error
;

paniclog:
    PANICLOG
    colon
    panic
;

panic:
    IDENTIFIER
    {
	panic_filename = xstrdup(yytext);
	expect = "default setting or 'users'";
    }
|
    {
	expect = "panic-logfilename";
    }
    error
;

nokills:
    NOKILLS
    {
	kill_processes = 0;
    };

showextra:
    EXTRA
    {
	show_extra = 1;
    };

showdirect:
    DIRECT
    {
	show_direct = 1;
    };

nodestinations:
    NODESTINATIONS
    {
	show_destinations = 0;
    };

shownums:
    SHOWNUMS
    {
	if (cb_mode != mode_callback)
	    yysemantic("'phonenumbers' only valid for mode callback");
	show_phonenumbers = 1;
    };

retry:
    RETRY
    {
	if (cb_mode != mode_callback)
	    yysemantic("'retry' only valid for mode callback");
    }
    colon
    nretries;

nretries:
    NUMBER
    {
	ntries = atoi(yytext);
	expect = "default setting or 'users'";
    }
|
    {
	expect = "Maximum callback retries expected";
    }
    error
;
    
modemgetty:
    MODEMGETTY
    colon
    modem
;

modem:
    IDENTIFIER
    {
	modem_getty = xstrdup(yytext);
	expect = "default setting or 'users'";
    }
|
    {
	expect = "modem_getty specification";
    }
    error
;

gettydefault:
    GETTYPATH
    colon
    getty
;

getty:
    IDENTIFIER
    {
	getty_path = xstrdup(yytext);
	expect = "default setting or 'users'";
    }
|
    {
	expect = "getty-configuration filename";
    }
    error
;

linesection:
    LINE
    colon
    ttyline
;

ttyline:
    IDENTIFIER
    {
	tty_line = xstrdup(yytext);
	expect = "default setting or 'users'";
    }
|
    {
	expect = "default ttyline";
    }
    error
;

pathsection:
    PATH
    colon
    pathname
;

pathname:
    IDENTIFIER
    {
	base_path = xstrdup(yytext);
	expect = "default setting or 'users'";
    }
|
    {
	expect = "Callback path";
    }
    error
;

scratchfile:
    scratch_keyword
    colon
    tmpname
;

scratch_keyword:
    SCRATCH
    {
	if (cb_mode != mode_callback)
	    yysemantic("'scratch' only valid for mode callback");
    }
;

tmpname:
    IDENTIFIER
    {
	tmp_filename = xstrdup(yytext);
	expect = "default setting or 'users'";
    }
|
    {
	expect = "Scratch-filename";
    }
    error
;

usersection:
    USERS
    colon
    users
;

users:
    users
    user
|
    user
;    

user:
    username
    colon
    grouplist
|
    {
	expect = "username";
    }
    error
;

username:
    IDENTIFIER
    {
	define_user(yytext);
    }
;

grouplist:
    grouplist
    {
	expect = "','";
    }
    ','
    group
|
    group
;    

group:
    IDENTIFIER
    {
	addgroup(yytext);
    }
|
    {
	expect = "groupname";
    }
    error
;

destinationsection:
    DESTINATIONS
    colon
    destinations
;

destinations:
    destinations
    destination
|
    destination
;    

destination:
    groupid
    {
	expect = "earlier 'using' or ':'";
    }
    ':'
    target
    mode
;

groupid:
    IDENTIFIER
    {
	define_group(yytext);
    }
|
    {
	expect = "groupname";
    }
    error
;

target:
    IDENTIFIER
    {
	set_target(yytext);
    }
|
    {
	expect = "target computer";
    }
    error
;

mode:
    DIRECT
    {
	set_mode(direct_mode);
    }
|
    EXTRA
    {
	set_mode(extra_mode);
    }
|
    phone_number
|
    {
	expect = "'direct', 'extra', or phonenumber";
    }
    error
;

phone_number:
    NUMBER
    {
	set_phone(yytext);
	expect = "'using' or groupname";
    }
    opt_file
;


opt_file:
    USING
    filename
|
    /*	empty */
;    

filename:
    IDENTIFIER
    {
	set_file(yytext);
    }
|
    {
	expect = "filename";
    }
    error
;


colon:
    {
	expect = "':'";
    }
    ':'
;
