439 |
|
|
440 |
[This section is missing :-P] |
[This section is missing :-P] |
441 |
|
|
|
|
|
442 |
@node Rule System, Invoking Anubis, Configuration, Top |
@node Rule System, Invoking Anubis, Configuration, Top |
443 |
@chapter The Rule System |
|
444 |
@cindex Basic regular expressions |
The rule system is a core part of Anubis system. It can be regarded |
445 |
@cindex Extended regular expressions |
as a program that is executed for every outgoing message. It is |
446 |
@cindex Perl regular expressions |
defined in @dfn{RULE} section, which begins with a |
447 |
@cindex rules |
@w{@code{---BEGIN RULE---}} and ends with an @w{@code{---END---}} |
448 |
@cindex rule system |
statements. |
449 |
@cindex regex |
|
450 |
@cindex regular expressions |
The statements within this section are executed sequentially. |
451 |
|
Each statement is either an @dfn{action} or a @dfn{conditional |
452 |
GNU Anubis' rule system is based on @dfn{regular expressions} (@dfn{POSIX Basic}, |
statement}. |
453 |
@dfn{POSIX Extended}, or @dfn{Perl regular expressions}). All of them can be |
|
454 |
used in a run time. |
An @dfn{action} is a statement defining an operation to be performed |
455 |
|
over the message. Syntactically, each action is |
456 |
According to the GNU's documentation, a @dfn{regular expression} |
|
457 |
(or @dfn{regexp}, or @dfn{pattern}) is a text string that describes some |
@example |
458 |
(mathematical) set of strings. A regexp @var{r} @dfn{matches} a string @var{s} |
@var{command} [=] @var{right-hand-side} |
459 |
if @var{s} is in the set of strings described by @var{r}. For more information |
@end example |
460 |
about @dfn{regular expressions}, read the GNU regular expression library manual |
@noindent |
461 |
and the regex manual. In addition, you can also read the Perl regular expressions |
|
462 |
manual. |
Where @var{command} specifies a particular operation and |
463 |
|
@var{right-hand-side} specifies the arguments for it. The equal sign |
464 |
The rule system is available only for GNU Anubis clients, |
is optional. |
465 |
so it can only be used in the user configuration file. |
|
466 |
The whole rule system starts with the @w{@code{---BEGIN RULE---}} line, |
A @dfn{conditional statement} defines the control flow in the section. |
467 |
and the @w{@code{---END---}} line ends it. |
It allows to execute arbitrary actions depending on whether a certain |
468 |
|
condition is met. A conditional statement in its simplest form is: |
469 |
|
|
470 |
|
@example |
471 |
|
if @var{part} [@var{flags}] @var{cond-expr} |
472 |
|
@var{action-list-1} |
473 |
|
fi |
474 |
|
@end example |
475 |
|
@noindent |
476 |
|
|
477 |
|
The @var{part} specifies which part of the input should be considered |
478 |
|
when evaluating the condition. It is either @samp{command}, meaning |
479 |
|
the text of an smtp command issued while sending the message, or |
480 |
|
@samp{header}, meaning the value of an RFC822 header. Either of the |
481 |
|
two may be followed by the name of the corresponding command or |
482 |
|
header enclosed in square braquets. If this part is missing, all |
483 |
|
command or headers will be searched. |
484 |
|
|
485 |
|
The optional @var{flags} determine which type of |
486 |
|
regular expressions is used in subsequent conditional expression. It |
487 |
|
will be described in detail in the section @ref{Regular expressions}. |
488 |
|
The @var{cond-expr} is a @dfn{conditional expression}. |
489 |
|
It consists of a series of @dfn{conditions} joined together with |
490 |
|
boolean operators @samp{and} or @samp{or} (@pxref{Boolean operators}). |
491 |
|
Each condition is: |
492 |
|
|
493 |
|
@table @asis |
494 |
|
@item = @var{regexp} |
495 |
|
Returns true if the requested part of the input matches the given regular |
496 |
|
expression (@var{regexp}). |
497 |
|
|
498 |
|
@item != @var{regexp} |
499 |
|
Returns true if the requested part of the input does not match the given |
500 |
|
regular expression. |
501 |
|
|
502 |
|
@item not @var{condition} |
503 |
|
Reverses the sense of @var{condition} |
504 |
|
|
505 |
|
@item ( @var{cond-expr} ) |
506 |
|
Returns the result of the conditional expression in parentheses. This |
507 |
|
is useful for changing operator precedence. |
508 |
|
@end table |
509 |
|
|
510 |
|
The simplest example: |
511 |
|
|
512 |
|
@example |
513 |
|
if header [Subject] "^ *Re:" |
514 |
|
... |
515 |
|
fi |
516 |
|
@end example |
517 |
|
|
518 |
|
The actions represented by @dots{} will be executed only if the |
519 |
|
@samp{Subject:} header of the message starts with @samp{Re:} optionally |
520 |
|
preceeded by any amount of whitespace. |
521 |
|
|
522 |
|
The more elaborate form of a conditional allows you to choose among |
523 |
|
the two different action sets depending on a given condition. The |
524 |
|
syntax is: |
525 |
|
|
526 |
|
@example |
527 |
|
if @var{part} [@var{flags}] @var{cond-expr} |
528 |
|
@var{action-list-1} |
529 |
|
else |
530 |
|
@var{action-list-2} |
531 |
|
fi |
532 |
|
@end example |
533 |
|
@noindent |
534 |
|
|
535 |
|
Here, The @var{action-list-1} is executed if the condition |
536 |
|
@var{cond-expr} is met. Otherwise, @var{action-list-2} is |
537 |
|
executed. |
538 |
|
|
539 |
|
@example |
540 |
|
if @var{part} [@var{flags}] @var{cond-expr} |
541 |
|
@var{action-list-1} |
542 |
|
else |
543 |
|
@var{action-list-2} |
544 |
|
fi |
545 |
|
@end example |
546 |
|
@noindent |
547 |
|
|
548 |
|
Note also, that in the examples above any of the statements |
549 |
|
@var{action-list} may contain conditionals, so that conditinal |
550 |
|
statements may be nested. This allows to create very sophisticated |
551 |
|
rule sets. |
552 |
|
|
553 |
|
[FIXME: elaborate on this. Provide an example] |
554 |
|
|
555 |
@menu |
@menu |
556 |
* Grammar:: |
* Boolean operators:: |
557 |
* Action List:: |
* Regular expressions:: |
558 |
* Trigger:: |
* Action Lists:: |
559 |
|
* Triggers:: |
560 |
@end menu |
@end menu |
561 |
|
|
562 |
|
@node Boolean operators |
563 |
|
@subsection Boolean operators |
564 |
|
|
565 |
@node Grammar, Action List, Rule System, Rule System |
The following table lists the three boolean operators that can be used |
566 |
@section Grammar |
in Anubis conditional expressions in the order of increasing binding |
567 |
@cindex grammar |
strength: |
568 |
|
|
569 |
[This section is missing :-P] |
@itemize @samp |
570 |
|
@item OR |
571 |
|
@item AND |
572 |
|
@item NOT |
573 |
|
@end itemize |
574 |
|
|
575 |
|
As an example, let's consider the following statement: |
576 |
|
|
577 |
|
@example |
578 |
|
if header[X-Mailer] :scase "mutt" or header[X-Mailer] :scase "mail" \ |
579 |
|
and not header[Content-Type] "^multipart/mixed;.*" |
580 |
|
@var{action} |
581 |
|
fi |
582 |
|
@end example |
583 |
|
@noindent |
584 |
|
|
585 |
@node Action List, Trigger, Grammar, Rule System |
In this case the @var{action} will be executed if the @code{X-Mailer} |
586 |
@section The Action List |
header contains the word @samp{mutt}. The same @var{action} will also |
587 |
|
be executed if the @code{X-Mailer} header contains the word @samp{mail} |
588 |
|
@emph{and} the value of the @code{Content-Type} header does not begin |
589 |
|
with the string @samp{multipart/mixed}. |
590 |
|
|
591 |
|
Now, if we wished to execute the @var{action} for any message sent |
592 |
|
using @command{mail} or @command{mutt} whose @code{Content-Type} |
593 |
|
header does not begin with the string @samp{multipart/mixed}, we would |
594 |
|
write the following: |
595 |
|
|
596 |
|
@example |
597 |
|
if (header[X-Mailer] :scase "mutt" or header[X-Mailer] :scase "mail") \ |
598 |
|
and not header[Content-Type] "^multipart/mixed;.*" |
599 |
|
@var{action} |
600 |
|
fi |
601 |
|
@end example |
602 |
|
@noindent |
603 |
|
|
604 |
|
Notice the use of parentheses to change the binding strength of the |
605 |
|
boolean operators. |
606 |
|
|
607 |
|
@node Regular expressions |
608 |
|
@subsection Regular expressions |
609 |
|
|
610 |
|
GNU Anubis supports two types of regular expressions: POSIX (both |
611 |
|
basic and extended), and Perl-style regular expressions. Among this, |
612 |
|
the former are always supported, whereas the support for the latter |
613 |
|
depends on the configuration settings at compile time. |
614 |
|
|
615 |
|
By default, the POSIX regular expressions are expected. To use |
616 |
|
Perl-style ones, use the @code{:perlre} flag. For example: |
617 |
|
|
618 |
|
@example |
619 |
|
if header[Subject] :perlre "(?<=(?<!foo)bar)baz" |
620 |
|
@end example |
621 |
|
@noindent |
622 |
|
|
623 |
|
This will match any @code{Subject} header whose value |
624 |
|
matches an occurrence of @samp{baz} that is preceded by @samp{bar} |
625 |
|
which in turn is not preceded by @samp{foo}. |
626 |
|
|
627 |
|
Usually the regular expression patterns are always case-sensitive. |
628 |
|
The special flag, @code{:scase}, is provided to change this default. |
629 |
|
For example: |
630 |
|
|
631 |
|
@example |
632 |
|
if header[Subject] :scase "^re" |
633 |
|
@end example |
634 |
|
@noindent |
635 |
|
|
636 |
|
Will match a @code{Subject} header whose value starts with @samp{re}, |
637 |
|
@samp{Re} or @samp{RE}. |
638 |
|
|
639 |
|
For the detailed description of POSIX regular expressions, |
640 |
|
@xref{Top,,Regular Expression Library,regex,Regular Expression Library}. |
641 |
|
For information about Perl-style regular expressions, refer to the |
642 |
|
Perl documentation. |
643 |
|
|
644 |
|
@node Action Lists |
645 |
|
@subsection Action Lists |
646 |
@cindex Action List |
@cindex Action List |
647 |
|
|
648 |
An @dfn{action list} is a list of action commands, which control processing |
An @dfn{action list} is a list of action commands, which control processing |
649 |
of an outgoing messages. All action command names are case insensitive, so you |
of an outgoing messages. All action command names are case insensitive, so you |
650 |
can use for instance: @samp{add} or @samp{ADD} or @samp{AdD}, and so on. |
can use for instance: @samp{add} or @samp{ADD} or @samp{AdD}, and so on. |
651 |
|
|
|
@strong{Caution:} Some action commands below might not be compatible |
|
|
with GNU Anubis > 3.6.2, because this Manual has not been updated for |
|
|
a long time. |
|
|
|
|
652 |
@menu |
@menu |
653 |
* Editing Headers:: How to edit a message header on-the-fly. |
* Editing Headers:: How to edit a message header on-the-fly. |
654 |
* Inserting Files:: How to append text files to an outgoing message. |
* Inserting Files:: How to append text files to an outgoing message. |
655 |
* Mail Encryption:: How to encrypt a message on-the-fly. |
* Mail Encryption:: How to encrypt a message on-the-fly. |
656 |
* Scheme Programs:: How to execute an external Scheme programs. |
* Remailers:: How to enable the support for Remailers Type-I. |
657 |
* External Processor:: How to process a message body using an external tool. |
* External Processor:: How to process a message body using an external tool. |
658 |
|
|
659 |
* Command Summary:: A short command summary. |
* Command Summary:: A short command summary. |
660 |
* Quick Example:: A quick example of using an action list. |
* Quick Example:: A quick example of using an action list. |
661 |
@end menu |
@end menu |
662 |
|
|
663 |
@node Editing Headers, Inserting Files, Action List, Action List |
[FIXME: The nodes below are not revised yet] |
664 |
@subsection Editing Headers |
|
665 |
|
@node Editing Headers |
666 |
|
@subsubsection Editing Headers |
667 |
@cindex message header |
@cindex message header |
668 |
|
|
669 |
@table @samp |
@table @samp |
670 |
@item add header[@var{key}] @var{value} |
@item add header [@var{header-name}] @var{header-line} |
671 |
This action command adds a header line to an outgoing message. |
@itemx add [@var{header-name}] @var{header-line} |
672 |
The "header" keyword may be omitted. A @var{key} is the header |
This action command adds to the outgoing message the header |
673 |
name. For example: |
@var{header-name} with the value @var{header-line}. Both forms of |
674 |
|
the command are equivalent. For example: |
675 |
|
|
676 |
@example |
@example |
677 |
add header[X-Comment1] "GNU's Not Unix!" |
add [X-Comment] "GNU's Not Unix!" |
|
add [X-Comment2] "Support FSF!" |
|
678 |
@end example |
@end example |
679 |
|
|
680 |
@item remove header[@var{key}] |
@item remove = @var{header-line} (a regular expression) |
681 |
This action command removes the header lines that match a pattern |
This action command removes the header lines that match @var{header-line} |
682 |
from an outgoing message. The "header" keyword may be omitted. |
from an outgoing message. This has to be a regular expression. |
683 |
A @var{key} is the header name and it can be a regular expression |
For example: |
|
matching a set of header names for "remove". For example: |
|
684 |
|
|
685 |
@example |
@example |
686 |
remove header["^X-Mailer"] |
remove =^X-Mailer: |
|
remove ["^X-.*"] |
|
687 |
@end example |
@end example |
688 |
|
|
689 |
The first example will remove the @samp{X-Mailer:} line from |
This will remove the @samp{X-Mailer:} line from an outgoing |
690 |
an outgoing message, and the second one will remove all "X-*" |
message. |
|
header lines. |
|
691 |
|
|
692 |
@item modify header[@var{key}] [@var{new-key}] @var{value} |
@item modify = @var{old-header-line} >> @var{new-header-line} |
693 |
This action command modifies a message header line (entirely or partly). |
This action command modifies a message header line (entirely or partly). |
694 |
The "header" keyword may be omitted. A @var{key} is the header name. |
An old header line (must be a regular expression) and a new header line |
695 |
It may be a regular expression matching a set of header names. |
are separated with @code{ >> }, i.e. @code{@key{SPC}>>@key{SPC}}. |
|
A @var{new-key} is optional. |
|
696 |
|
|
697 |
For example, the following code will change the @samp{Reply-To:} |
For example, the following code will change the @samp{Reply-To:} |
698 |
line only if you would send an email to @url{friend@@somewhere.net}. |
line only if you would send an email to @url{friend@@somewhere.net}. |
699 |
|
|
700 |
@example |
@example |
701 |
@group |
@group |
702 |
if header[To] = ".*<?friend@@somewhere.net>?" |
if header =^To:.*<?friend@@somewhere.net>? |
703 |
modify header[Reply-To] "private@@somewhere.net" |
modify =^Reply-To: >> Reply-To: private@@somewhere.net |
704 |
fi |
fi |
705 |
@end group |
@end group |
706 |
@end example |
@end example |
710 |
|
|
711 |
@example |
@example |
712 |
@group |
@group |
713 |
if header[X-Mailer] = PINE |
if header =^X-Mailer: PINE |
714 |
modify header[X-Mailer] "The Big Boss" |
modify =^X-Mailer: >> X-Mailer: The Big Boss |
715 |
fi |
fi |
716 |
@end group |
@end group |
717 |
@end example |
@end example |
721 |
|
|
722 |
@example |
@example |
723 |
@group |
@group |
724 |
if header[X-Mailer] = "(.*)" |
if header =^X-Mailer: (.*) |
725 |
modify [X-Mailer] "The lousy mailer \1" |
modify =^X-Mailer: >> X-Mailer: The lousy mailer \1 |
726 |
fi |
fi |
727 |
@end group |
@end group |
728 |
@end example |
@end example |
730 |
It is allowed to make up to nine substitutions (range: \1---\9). |
It is allowed to make up to nine substitutions (range: \1---\9). |
731 |
@end table |
@end table |
732 |
|
|
733 |
|
@node Inserting Files |
734 |
@node Inserting Files, Mail Encryption, Editing Headers, Action List |
@subsubsection Inserting Files |
|
@subsection Inserting Files |
|
735 |
|
|
736 |
@table @samp |
@table @samp |
737 |
@item signature-file-append = @var{yes-or-no} |
@item signature-file-append = @var{yes-or-no} |
750 |
@end table |
@end table |
751 |
|
|
752 |
|
|
753 |
@node Mail Encryption, Scheme Programs, Inserting Files, Action List |
@node Mail Encryption |
754 |
@subsection Mail Encryption |
@subsubsection Mail Encryption |
755 |
@cindex GNU Privacy Guard, GnuPG |
@cindex GNU Privacy Guard, GnuPG |
756 |
@cindex Pretty Good Privacy, PGP |
@cindex Pretty Good Privacy, PGP |
757 |
@cindex GPG/PGP private key |
@cindex GPG/PGP private key |
798 |
gpg-sign = yes |
gpg-sign = yes |
799 |
@end group |
@end group |
800 |
@end example |
@end example |
|
@end table |
|
|
|
|
801 |
|
|
|
@node Scheme Programs, External Processor, Mail Encryption, Action List |
|
|
@subsection Executing Scheme Programs |
|
|
@cindex Scheme |
|
|
@cindex Guile |
|
|
|
|
|
@menu |
|
|
* ROT-13:: ROT-13 support. |
|
|
* Remailers:: How to enable the support for Remailers Type-I. |
|
|
@end menu |
|
|
|
|
|
|
|
|
@node ROT-13, Remailers, Scheme Programs, Scheme Programs |
|
|
@subsubsection ROT-13 |
|
|
@cindex ROT-13 |
|
|
|
|
|
@table @samp |
|
802 |
@item rot13-subject = @var{yes-or-no} |
@item rot13-subject = @var{yes-or-no} |
803 |
This command enables the simple ROT-13 message subject encoding. |
This command enables the simple ROT-13 message subject encoding. |
804 |
Value @samp{no} is the default. The ROT-13 encoding is a simple form |
Value @samp{no} is the default. The ROT-13 encoding is a simple form |
812 |
@end table |
@end table |
813 |
|
|
814 |
|
|
815 |
@node Remailers, , ROT-13, Scheme Programs |
@node Remailers |
816 |
@subsubsection Remailers Type-I |
@subsubsection Remailers Type-I |
817 |
@cindex remailer |
@cindex remailer |
818 |
|
|
855 |
@end table |
@end table |
856 |
|
|
857 |
|
|
858 |
@node External Processor, Command Summary, Scheme Programs, Action List |
@node External Processor |
859 |
@subsection Using an External Processor |
@subsubsection Using an External Processor |
860 |
|
|
861 |
@table @samp |
@table @samp |
862 |
@item external-body-processor = @var{file-name} [@var{args}] |
@item external-body-processor = @var{file-name} [@var{args}] |
865 |
crypto engine, a spell checker, some text generator, whatever. |
crypto engine, a spell checker, some text generator, whatever. |
866 |
@end table |
@end table |
867 |
|
|
868 |
|
@node Command Summary |
869 |
@node Command Summary, Quick Example, External Processor, Action List |
@subsubsection Command Summary |
|
@subsection Command Summary |
|
870 |
|
|
871 |
@example |
@example |
872 |
@group |
@group |
873 |
add header[@var{key}] @var{value} |
add = @var{header-line} |
874 |
remove header[@var{key}] @var{value} |
remove = @var{header-line} (a regular expression) |
875 |
modify header[@var{key}] [@var{new-key}] @var{value} |
modify = @var{old-header-line} >> @var{new-header-line} |
876 |
signature-file-append = @var{yes-or-no} |
signature-file-append = @var{yes-or-no} |
877 |
body-append = @var{file-name} |
body-append = @var{file-name} |
878 |
body-clear-append = @var{file-name} |
body-clear-append = @var{file-name} |
879 |
gpg-passphrase = @var{passphrase} |
gpg-passphrase = @var{passphrase} |
880 |
gpg-encrypt = @var{gpg-keys} |
gpg-encrypt = @var{gpg-keys} |
881 |
gpg-sign = @var{passphrase} or @samp{yes} if @samp{gpg-passphrase} is specified. |
gpg-sign = @var{passphrase} or @samp{yes} if @samp{gpg-passphrase} is specified. |
882 |
|
rot13-subject = @var{yes-or-no} |
883 |
|
rot13-body = @var{yes-or-no} |
884 |
|
rm-rrt = @var{email-address} |
885 |
|
rm-post = @var{news-group} |
886 |
|
rm-gpg = @var{gpg-key} |
887 |
|
rm-header = @var{header-line} |
888 |
|
rm-lt = @var{time} |
889 |
|
rm-rlt = @var{yes-or-no} |
890 |
external-body-processor = @var{file-name} [@var{args}] |
external-body-processor = @var{file-name} [@var{args}] |
891 |
@end group |
@end group |
892 |
@end example |
@end example |
893 |
|
|
894 |
|
|
895 |
@node Quick Example, , Command Summary, Action List |
@node Quick Example |
896 |
@subsection Quick Example |
@subsubsection Quick Example |
897 |
|
|
898 |
[This section is missing :-P] |
Here is a quick example of using an action list: |
899 |
|
|
900 |
|
@example |
901 |
|
@group |
902 |
|
---BEGIN RULE--- |
903 |
|
if header =^X-Mailer: |
904 |
|
remove =^X-Mailer: |
905 |
|
add = X-Comment: GNU's Not Unix! |
906 |
|
gpg-sign = @var{your passphrase} |
907 |
|
signature-file-append = yes |
908 |
|
fi |
909 |
|
---END--- |
910 |
|
@end group |
911 |
|
@end example |
912 |
|
|
913 |
|
@noindent |
914 |
|
The example above will remove (on-the-fly) the @samp{X-Mailer:} line from |
915 |
|
an outgoing message, add an extra header line (@samp{X-Comment:}), sign your |
916 |
|
message with your private key, and add a simple signature file from your |
917 |
|
home directory. |
918 |
|
|
|
@node Trigger, , Action List, Rule System |
|
|
@section The Trigger |
|
|
@cindex Trigger, The |
|
919 |
|
|
920 |
|
@node Triggers |
921 |
|
@subsection Triggers |
922 |
|
@cindex Triggers |
923 |
Adding the @samp{@@@@@var{rule-name}} code to your message header line, |
Adding the @samp{@@@@@var{rule-name}} code to your message header line, |
924 |
e.g. to a @samp{Subject} header line, triggers a rule named @var{rule-name}, |
e.g. to a @samp{Subject} header line, triggers a rule named @var{rule-name}, |
925 |
specified in a user configuration file in the following way: |
specified in a user configuration file in the following way: |
926 |
|
|
927 |
@example |
@example |
928 |
@group |
@group |
929 |
rule [:@var{tags}] "@var{rule-name}" |
rule [: @var{options}] =^@var{rule-name} |
930 |
@var{action-list} |
@var{action-list} |
931 |
done |
done |
932 |
@end group |
@end group |
933 |
@end example |
@end example |
934 |
|
|
935 |
|
@noindent |
936 |
|
@strong{Caution:} Plase note that there is no space after the @samp{=} |
937 |
|
character. |
938 |
|
|
939 |
An example: |
An example: |
940 |
|
|
941 |
@example |
@example |
942 |
@group |
@group |
943 |
---BEGIN RULE--- |
---BEGIN RULE--- |
944 |
rule "gpg-encrypt-john" |
rule =^gpg-encrypt-john |
945 |
gpg-encrypt = john's_gpg_key |
gpg-encrypt = john's_gpg_key |
946 |
done |
done |
947 |
---END--- |
---END--- |
961 |
@example |
@example |
962 |
@group |
@group |
963 |
---BEGIN RULE--- |
---BEGIN RULE--- |
964 |
rule "gpg-encrypt:(.*)" |
rule =^gpg-encrypt:(.*) |
965 |
gpg-encrypt = \1 |
gpg-encrypt = \1 |
966 |
add header[X-GPG-Comment] "Encrypted for \1" |
add = X-GPG-Comment: Encrypted for \1 |
967 |
done |
done |
968 |
---END--- |
---END--- |
969 |
@end group |
@end group |
976 |
without creating a separate rules for each user; thanks to back-references, |
without creating a separate rules for each user; thanks to back-references, |
977 |
those 3---4 lines are enough. |
those 3---4 lines are enough. |
978 |
|
|
|
|
|
979 |
@node Invoking Anubis, Sample Beginning, Rule System, Top |
@node Invoking Anubis, Sample Beginning, Rule System, Top |
980 |
@chapter Invoking GNU Anubis |
@chapter Invoking GNU Anubis |
981 |
@cindex command line |
@cindex command line |