depcomp
autom4te.cache
+GRAMMAR
man_MANS = fw.1
EXTRA_DIST = \
- $(man_MANS) \
+ fw.1.in GRAMMAR \
+ make-manpage \
debian/changelog debian/copyright debian/control debian/rules
+BUILT_SOURCES = mantext.c
+
+$(srcdir)/GRAMMAR: fw.1.in make-manpage
+ perl $(srcdir)/make-manpage text <$(srcdir)/fw.1.in >$@.new
+ mv $@.new $@
+
+fw.1: fw.1.in make-manpage
+ perl $(srcdir)/make-manpage man <$(srcdir)/fw.1.in >$@.new
+ mv $@.new $@
+
+mantext.c: fw.1.in make-manpage
+ perl $(srcdir)/make-manpage c <$(srcdir)/fw.1.in >$@.new
+ mv $@.new $@
+
fw_SOURCES = \
- chan.c conf.c endpt.c fw.c reffd.c scan.c \
- chan.h conf.h endpt.h fw.h reffd.h scan.h \
+ chan.c conf.c endpt.c fw.c mantext.c reffd.c scan.c \
+ chan.h conf.h endpt.h fw.h mantext.h reffd.h scan.h \
\
source.c source.h target.h \
exec.c file.c socket.c \
acl.c fattr.c identify.c privconn.c \
acl.h fattr.h identify.h privconn.h rlimits.h
+CLEANFILES = $(BUILT_SOURCES) fw.1
+MAINTAINERCLEANFILES = $(srcdir)/GRAMMAR
+
##----- That's all, folks ---------------------------------------------------
dh_testdir -a
dh_testroot -a
dh_compress -a
- dh_installdocs -a grammar
+ dh_installdocs -a GRAMMAR
dh_strip -a
dh_shlibdeps -a
dh_gencontrol -a
.de GE
.PP
..
+.de GL
+..
.
.de OS
.PP
.de OE
.RE
..
+.de OL
+..
.
.\" --- Other bits of styling ---
.
disambiguates local options.
.PP
The following file attribute options are supported:
-.OS "File attribute options (`fattr')"
+.OS "File attributes (`fattr')"
.IB prefix .fattr.mode
.RB [ = ]
.I mode
.RB ` , '
do not have to be quoted within the mode string.
.OE
-.OS "File attribute options (`fattr')"
+.OS "File attributes (`fattr')"
.IB prefix .fattr.owner
.RB [ = ]
.I user
are accepted in place of
.BR owner .
.OE
-.OS "File attribute options (`fattr')"
+.OS "File attributes (`fattr')"
.IB prefix .fattr.group
.RB [ = ]
.I group
The syntax of
.B file
sources and targets is like this:
-.GS "File sources and targets"
+.GS "File source and target"
.I source
::=
.I file
the new data is appended to the file.
.OE
.OS "File options"
-.BR file.fattr.*
+.BR file.fattr. *
.OD
The
.B file
.br
.I target
::=
-exec
+.I exec
.br
.I exec
::=
.OD
Clears the program's environment.
.OE
-.PP
+.OS "Exec options"
.B exec.env.unset
.I var
.OD
Address types also provide their own options.
.
.SS "The `inet' socket address type"
+.GL "Socket source and target"
+.OL "Socket options"
The
.B inet
address type provides access to TCP ports. The
.OS "Socket options"
.B socket.inet.source.addr
.RB [ = ]
-.RR any | \c
+.BR any | \c
.I addr
.OD
Specify the IP address on which to listen for incoming connections. The
.OS "Socket options"
.B socket.inet.dest.addr
.RB [ = ]
-.RR any | \c
+.BR any | \c
.I addr
.OD
Specify the IP address to bind the local socket to when making an
is to allow all clients.
.
.SS "The `unix' socket address type"
+.GL "Socket source and target"
+.OL "Socket options"
The
.B unix
address type allows access to Unix-domain sockets. The syntax for
.\"--------------------------------------------------------------------------
.SH "GRAMMAR SUMMARY"
.
-.SS "Basic syntax"
-.I file
-::=
-.I empty
-|
-.I file
-.I stmt
-.RB [ ; ]
-.br
-.I stmt
-::=
-.I option-stmt
-|
-.I fw-stmt
-.br
-.I fw-stmt
-::=
-.B fw
-.I source
-.I options
-.RB [ to | \-> ]
-.I target
-.I options
-.br
-.I options
-::=
-.B {
-.I option-seq
-.B }
-.br
-.I option-seq
-::=
-.I empty
-|
-.I option-stmt
-.RB [ ; ]
-.I option-seq
-.
-.SS "Option syntax"
-.I option-stmt
-::=
-.I q-option
-.br
-.I q-option
-::=
-.I option
-.br
- |
-.I prefix
-.B .\&
-.I q-option
-.br
- |
-.I prefix
-.B {
-.I option-seq
-.B }
-.br
-.I prefix
-::=
-.I word
-.
-.SS "File source and target"
-.I source
-::=
-.I file
-.br
-.I target
-::=
-.I file
-.br
-.I file
-::=
-.B file
-.RB [ .\& ]
-.I fspec
-.RB [ ,
-.IR fspec ]
-.br
-.I fspec
-::=
-.I fd-spec
-|
-.I name-spec
-|
-.I null-spec
-.br
-.I fd-spec
-::=
-.RB [[ : ] fd [ : ]]
-.IR number \c
-.RB | stdin | stdout
-.br
-.I name-spec
-::=
-.RB [[ : ] name [ : ]]
-.I file-name
-.br
-.I file-name
-::=
-.I path-seq
-|
-.B [
-.I path-seq
-.B ]
-.br
-.I path-seq
-::=
-.I path-elt
-|
-.I path-seq
-.I path-elt
-.br
-.I path-elt
-::=
-.B /
-|
-.I word
-.br
-.I null-spec
-::=
-.RB [ : ] null [ : ]
-.
-.SS "Exec source and target"
-.I source
-::=
-.I exec
-.br
-.I target
-::=
-exec
-.br
-.I exec
-::=
-.BR exec
-.RB [ .\& ]
-.I cmd-spec
-.br
-.I cmd-spec
-::=
-.I shell-cmd
-|
-.RI [ prog-name ]
-.B [
-.I argv0
-.I arg-seq
-.B ]
-.br
-.I arg-seq
-::=
-.I word
-|
-.I arg-seq
-.I word
-.br
-.I shell-cmd
-::=
-.I word
-.br
-.I argv0
-::=
-.I word
-.
-.SS "Socket source and target"
-.ll +8i
-.I source
-::=
-.I socket-source
-.br
-.I target
-::=
-.I socket-target
-.br
-.I socket-source
-::=
-.RB [ socket [ .\& ]]
-.RB [[ : ] \c
-.IR addr-type \c
-.RB [ : ]]
-.I source-addr
-.br
-.I socket-target
-::=
-.RB [ socket [ .\& ]]
-.RB [[ : ] \c
-.IR addr-type \c
-.RB [ : ]]
-.I target-addr
-.ll -8i
-.PP
-.I inet-source-addr
-::=
-.RB [ port ]
-.I port
-.br
-.I inet-target-addr
-::=
-.I address
-.RB [ : ]
-.I port
-.br
-.I address
-::=
-.I addr-elt
-|
-.I address
-.I addr-elt
-.br
-.I addr-elt
-::=
-.B .\&
-|
-.I word
-.PP
-.I unix-source-addr
-::=
-.I file-name
-.br
-.I unix-target-addr
-::=
-.I file-name
-.
+@@@ grammar
.\"--------------------------------------------------------------------------
.SH "OPTION SUMMARY"
.
-.SS "File attributes (`fattr')"
-.IB prefix .fattr.mode
-.RB [ = ]
-.I mode
-.br
-.IB prefix .fattr.owner
-.RB [ = ]
-.I user
-.br
-.IB prefix .fattr.group
-.RB [ = ]
-.I group
-.
-.SS "File options"
-.B file.create
-.RB [ = ]
-.BR yes | no
-.br
-.B file.open
-.RB [ = ]
-.BR no | truncate | append
-.br
-.BR file.fattr. *
-.
-.SS "Exec options"
-.B exec.logging
-.RB [ = ]
-.BR yes | no
-.br
-.B exec.dir
-.RB [ = ]
-.I file-name
-.br
-.B exec.root
-.RB [ = ]
-.I file-name
-.br
-.B exec.user
-.RB [ = ]
-.I user
-.br
-.B exec.group
-.RB [ = ]
-.I group
-.br
-.BI exec.rlimit. limit \c
-.RB [ .hard | .soft ]
-.RB [ = ]
-.I value
-.br
-.B exec.env.clear
-.br
-.B exec.env.unset
-.I var
-.br
-.BR exec.env. [ set ]
-.I var
-.RB [ = ]
-.I value
-.
-.SS "Socket options"
-.B socket.conn
-.RB [ = ]
-.IR number | \c
-.BR unlimited | one-shot
-.br
-.B socket.listen
-.RB [ = ]
-.I number
-.br
-.B socket.logging
-.RB [ = ]
-.BR yes | no
-.PP
-.BR socket.inet.source. [ allow | deny ]
-.RB [ host ]
-.I addr
-.RB [ /
-.IR addr ]
-.br
-.BR socket.inet.source. [ allow | deny ]
-.B priv-port
-.br
-.B socket.inet.source.addr
-.RB [ = ]
-.BR any | \c
-.I addr
-.br
-.B socket.inet.dest.addr
-.RB [ = ]
-.BR any | \c
-.I addr
-.br
-.B socket.inet.dest.priv-port
-.RB [=]
-.BR yes | no
-.PP
-.BR socket.unix.fattr. *
-.
+@@@ option
.\"--------------------------------------------------------------------------
.SH "BUGS"
.
#include "fattr.h"
#include "file.h"
#include "fw.h"
+#include "mantext.h"
#include "privconn.h"
#include "scan.h"
#include "socket.h"
static void grammar(FILE *fp)
{
version(fp);
- pquis(fp, "\n\
-Grammar summary\n\
-\n\
-Basic syntax\n\
- FILE ::= EMPTY | FILE STMT [`;']\n\
- STMT ::= OPTION-STMT | FW-STMT\n\
- FW-STMT ::= `fw' SOURCE OPTIONS [`to'|`->'] TARGET OPTIONS\n\
- OPTIONS ::= `{' OPTION-SEQ `}'\n\
- OPTION-SEQ ::= EMPTY | OPTION-STMT [`;'] OPTION-SEQ\n\
-\n\
-Option syntax\n\
- OPTION-STMT ::= Q-OPTION\n\
- Q-OPTION ::= OPTION\n\
- | PREFIX `.' Q-OPTION\n\
- | PREFIX `{' OPTION-SEQ `}'\n\
- PREFIX ::= WORD\n\
-\n\
-File source and target\n\
- SOURCE ::= FILE\n\
- TARGET ::= FILE\n\
- FILE ::= `file' [`.'] FSPEC [`,' FSPEC]\n\
- FSPEC ::= FD-SPEC | NAME-SPEC | NULL-SPEC\n\
- FD-SPEC ::= [[`:']`fd'[`:']] NUMBER|`stdin'|`stdout'\n\
- NAME-SPEC ::= [[`:']`name'[`:']] FILE-NAME\n\
- FILE-NAME ::= PATH-SEQ | [ PATH-SEQ ]\n\
- PATH-SEQ ::= PATH-ELT | PATH-SEQ PATH-ELT\n\
- PATH-ELT ::= `/' | WORD\n\
- NULL-SPEC ::= [`:']`null'[`:']\n\
-\n\
-Exec source and target\n\
- SOURCE ::= EXEC\n\
- TARGET ::= EXEC\n\
- EXEC ::= `exec' [`.'] CMD-SPEC\n\
- CMD-SPEC ::= SHELL-CMD | [PROG-NAME] `[' ARGV0 ARG-SEQ `]'\n\
- ARG-SEQ ::= WORD | ARG-SEQ WORD\n\
- SHELL-CMD ::= WORD\n\
- ARGV0 ::= WORD\n\
-\n\
-Socket source and target\n\
- SOURCE ::= SOCKET-SOURCE\n\
- TARGET ::= SOCKET-TARGET\n\
- SOCKET-SOURCE ::= [`socket'[`.']] [[`:']ADDR-TYPE[`:']] SOURCE-ADDR\n\
- SOCKET-TARGET ::= [`socket'[`.']] [[`:']ADDR-TYPE[`:']] TARGET-ADDR\n\
-\n\
- INET-SOURCE-ADDR ::= [`port'] PORT\n\
- INET-TARGET-ADDR ::= ADDRESS [`:'] PORT\n\
- ADDRESS ::= ADDR-ELT | ADDRESS ADDR-ELT\n\
- ADDR-ELT ::= `.' | WORD\n\
-\n\
- UNIX-SOURCE-ADDR ::= FILE-NAME\n\
- UNIX-TARGET-ADDR ::= FILE-NAME\n\
-");
+ fputs("\nGrammar summary\n\n", fp);
+ fputs(grammar_text, fp);
}
static void options(FILE *fp)
{
version(fp);
- pquis(fp, "\n\
-Options summary\n\
-\n\
-File attributes (`fattr')\n\
- prefix.FATTR.MODE [=] MODE\n\
- prefix.FATTR.OWNER [=] USER\n\
- prefix.FATTR.GROUP [=] GROUP\n\
-\n\
-File options\n\
- file.create [=] yes|no\n\
- file.open [=] no|truncate|append\n\
- file.fattr.*\n\
-\n\
-Exec options\n\
- exec.logging [=] yes|no\n\
- exec.dir [=] FILE-NAME\n\
- exec.root [=] FILE-NAME\n\
- exec.user [=] USER\n\
- exec.group [=] GROUP\n\
- exec.rlimit.LIMIT[.hard|.soft] [=] VALUE\n\
- exec.env.clear\n\
- exec.env.unset VAR\n\
- exec.env.[set] VAR [=] VALUE\n\
-\n\
-Socket options\n\
- socket.conn [=] NUMBER|unlimited|one-shot\n\
- socket.listen [=] NUMBER\n\
- socket.logging [=] yes|no\n\
-\n\
- socket.inet.source.[allow|deny] [host] ADDR [/ ADDR]\n\
- socket.inet.source.[allow|deny] priv-port\n\
- socket.inet.source.addr [=] any|ADDR\n\
- socket.inet.dest.addr [=] any|ADDR\n\
- socket.inet.dest.priv-port [=] yes|no\n\
-\n\
- socket.unix.fattr.*\n\
-");
+ fputs("\nOption summary\n\n", fp);
+ fputs(option_text, fp);
}
/* --- @main@ --- *
+++ /dev/null
-Basic syntax
- FILE ::= EMPTY | FILE STMT [`;']
- STMT ::= OPTION-STMT | FW-STMT
- FW-STMT ::= `fw' SOURCE OPTIONS [`to'|`->'] TARGET OPTIONS
- OPTIONS ::= `{' OPTION-SEQ `}'
- OPTION-SEQ ::= EMPTY | OPTION-STMT [`;'] OPTION-SEQ
-
-Option syntax
- OPTION-STMT ::= Q-OPTION
- Q-OPTION ::= OPTION
- | PREFIX `.' Q-OPTION
- | PREFIX `{' OPTION-SEQ `}'
- PREFIX ::= WORD
-
-File source and target
- SOURCE ::= FILE
- TARGET ::= FILE
- FILE ::= `file' [`.'] FSPEC [`,' FSPEC]
- FSPEC ::= FD-SPEC | NAME-SPEC | NULL-SPEC
- FD-SPEC ::= [[`:']`fd'[`:']] NUMBER|`stdin'|`stdout'
- NAME-SPEC ::= [[`:']`file'[`:']] FILE-NAME
- FILE-NAME ::= PATH-SEQ | [ PATH-SEQ ]
- PATH-SEQ ::= PATH-ELT | PATH-SEQ PATH-ELT
- PATH-ELT ::= `/' | WORD
- NULL-SPEC ::= [`:']`null'[`:']
-
-Exec source and target
- SOURCE ::= EXEC
- TARGET ::= EXEC
- EXEC ::= `exec' [`.'] CMD-SPEC
- CMD-SPEC ::= SHELL-CMD | [PROG-NAME] `[' ARGV0 ARG-SEQ `]'
- ARG-SEQ ::= WORD | ARG-SEQ WORD
- SHELL-CMD ::= WORD
- ARGV0 ::= WORD
-
-Socket source and target
- SOURCE ::= SOCKET-SOURCE
- TARGET ::= SOCKET-TARGET
- SOCKET-SOURCE ::= [`socket'[`.']] [[`:']ADDR-TYPE[`:']] SOURCE-ADDR
- SOCKET-TARGET ::= [`socket'[`.']] [[`:']ADDR-TYPE[`:']] TARGET-ADDR
-
- INET-SOURCE-ADDR ::= [`port'] PORT
- INET-TARGET-ADDR ::= ADDRESS [`:'] PORT
- ADDRESS ::= ADDR-ELT | ADDRESS ADDR-ELT
- ADDR-ELT ::= `.' | WORD
-
- UNIX-SOURCE-ADDR ::= FILE-NAME
- UNIX-TARGET-ADDR ::= FILE-NAME
-
-File attributes (`fattr')
- PREFIX.fattr.mode [=] MODE
- PREFIX.fattr.owner [=] USER
- PREFIX.fattr.group [=] GROUP
-
-File options
- file.create [=] yes|no
- file.open [=] no|truncate|append
- file.fattr.*
-
-Exec options
- exec.logging [=] yes|no
- exec.dir [=] FILE-NAME
- exec.root [=] FILE-NAME
- exec.user [=] USER
- exec.group [=] GROUP
- exec.rlimit.LIMIT[.hard|.soft] [=] VALUE
- exec.env.clear
- exec.env.unset VAR
- exec.env.[set] VAR [=] VALUE
-
-Socket options
- socket.conn [=] NUMBER|unlimited|one-shot
- socket.logging [=] yes|no
-
- socket.inet.source.[allow|deny] priv-port
- socket.inet.source.[allow|deny] [host] ADDR [/ ADDR]
- socket.inet.source.addr [=] any|ADDR
- socket.inet.dest.addr [=] any|ADDR
- oscket.inet.dest.priv-port [=] yes|no
-
- socket.unix.source.fattr.*
--- /dev/null
+#! /usr/bin/perl
+
+%ch = ();
+%ord = ();
+$chunk = undef;
+$mode = $ARGV[0] || die "mode?";
+shift;
+
+sub setup {
+ my $r = \%{$ch{$_[0]}};
+ if (exists $r->{$1}) {
+ $r->{$1} .= ".br\n";
+ } else {
+ push @{$ord{$_[0]}}, $1;
+ }
+ $chunk = \$r->{$1};
+}
+while (<>) {
+ if (/^\.GS (.*)$/) {
+ setup('grammar');
+ } elsif (/^\.OS (.*)$/) {
+ setup('option');
+ } elsif (/^\.GE/ || /^\.OD/) {
+ $chunk = undef;
+ } elsif (/^\.GL (.*)$/) {
+ $ch{'grammar'}{$1} .= ".PP\n";
+ next;
+ } elsif (/^\.OL (.*)$/) {
+ $ch{'option'}{$1} .= ".PP\n";
+ next;
+ } elsif (/^@@@ (\w+)$/) {
+ if ($mode eq 'man') {
+ foreach $head (@{$ord{$1}}) {
+ print ".SS $head\n";
+ print $ch{$1}{$head};
+ }
+ }
+ next;
+ } else {
+ $$chunk .= $_ if $chunk;
+ }
+ print if $mode eq 'man';
+}
+
+sub ital { uc($_[0]); }
+sub bold { $head eq 'option' ? $_[0] : "`$_[0]'"; }
+sub rom { $_[0]; }
+
+sub deroff {
+ $head = $_[0];
+ my $chsep = "";
+ my $out = "";
+ for my $chunk (@{$ord{$head}}) {
+ (my $chh = $chunk) =~ s/^"(.*)"$/$1/;
+ $out .= "$chsep$chh\n";
+ $chsep = "\n";
+ $sep = "\t";
+ for (split /\n/, $ch{$head}{$chunk}) {
+ s/\s$//; s/\\\&//g; s/\\-/-/g;
+ if (/^\.I (.*)$/) {
+ $out .= $sep . ital($1);
+ $sep = " ";
+ } elsif (/^\.B (.*)$/) {
+ $out .= $sep . bold($1);
+ $sep = " ";
+ } elsif (/^\.RB (.*)/) {
+ my $i = 1; $out .= $sep; $sep = " ";
+ for my $w (split ' ', $1) {
+ if ($w eq "\\c") {
+ $sep = ""; last;
+ }
+ $out .= ($i++%2 ? rom($w) : bold($w));
+ }
+ } elsif (/^\.BR (.*)/) {
+ my $i = 1; $out .= $sep; $sep = " ";
+ for my $w (split ' ', $1) {
+ if ($w eq "\\c") {
+ $sep = ""; last;
+ }
+ $out .= ($i++%2 ? bold($w) : rom($w));
+ }
+ } elsif (/^\.IR (.*)/) {
+ my $i = 1; $out .= $sep; $sep = " ";
+ for my $w (split ' ', $1) {
+ if ($w eq "\\c") {
+ $sep = ""; last;
+ }
+ $out .= ($i++%2 ? ital($w) : rom($w));
+ }
+ } elsif (/^\.RI (.*)/) {
+ my $i = 1; $out .= $sep; $sep = " ";
+ for my $w (split ' ', $1) {
+ if ($w eq "\\c") {
+ $sep = ""; last;
+ }
+ $out .= ($i++%2 ? rom($w) : ital($w));
+ }
+ } elsif (/^\.BI (.*)/) {
+ my $i = 1; $out .= $sep; $sep = " ";
+ for my $w (split ' ', $1) {
+ if ($w eq "\\c") {
+ $sep = ""; last;
+ }
+ $out .= ($i++%2 ? bold($w) : ital($w));
+ }
+ } elsif (/^\.IB (.*)/) {
+ my $i = 1; $out .= $sep; $sep = " ";
+ for my $w (split ' ', $1) {
+ if ($w eq "\\c") {
+ $sep = ""; last;
+ }
+ $out .= ($i++%2 ? ital($w) : bold($w));
+ }
+ } elsif (/^\.$/) {
+ # foo
+ } elsif (/^[^.]/) {
+ $out .= $sep . $_;
+ $sep = " ";
+ } elsif (/^\.br$/ || /^\.PP$/) {
+ $out .= "\n";
+ $sep = "\t";
+ }
+ }
+ $out .= "\n";
+ }
+ return $out;
+}
+
+if ($mode eq 'c') {
+ print <<EOF;
+/* -*-c-*-
+ *
+ * Generated grammar and options summary
+ */
+
+#include "mantext.h"
+
+EOF
+ for $head (keys %ch) {
+ print "const char ${head}_text[] = \"\\\n";
+ $text = deroff($head);
+ $text =~ s/\n/\\n\\\n/g;
+ print $text;
+ print "\";\n\n";
+ }
+} elsif ($mode eq 'text') {
+ my $sep = "";
+ for $head (keys %ch) {
+ print $sep, deroff($head);
+ $sep = "\n";
+ }
+}
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id$
+ *
+ * Grammar declarations
+ *
+ * (c) 2006 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of the `fw' port forwarder.
+ *
+ * `fw' 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * `fw' is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with `fw'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef MANTEXT_H
+#define MANTEXT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*----- Data provided -----------------------------------------------------*/
+
+extern const char grammar_text[];
+extern const char option_text[];
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif