author | Olivier Brunel
<jjk@jjacky.com> 2018-01-22 21:07:21 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2018-01-23 17:16:51 UTC |
parent | 500966b9e89255b07484912097d2b8ddda3334a3 |
doc/aa-bw.pod | +68 | -0 |
package/modes | +1 | -0 |
package/targets.mak | +2 | -0 |
src/utils/aa-bw.c | +131 | -0 |
src/utils/deps-exe/aa-bw | +2 | -0 |
diff --git a/doc/aa-bw.pod b/doc/aa-bw.pod new file mode 100644 index 0000000..7f0722f --- /dev/null +++ b/doc/aa-bw.pod @@ -0,0 +1,68 @@ +=head1 NAME + +aa-bw - Performs simple comparison between two numbers + +=head1 SYNOPSIS + +B<aa-bw> [B<-a> | B<-A> | B<-e>] [B<-p>] I<NUM1> I<NUM2> + +=head1 OPTIONS + +=over + +=item B<-A, --all> + +Success when I<NUM1> & I<NUM2> == I<NUM2> + +=item B<-a, --and> + +Success when I<NUM1> & I<NUM2> is non null (!= 0) + +This is the default is neither B<--all> nor B<--equal> is used. + +=item B<-e, --equal> + +Success when I<NUM1> == I<NUM2> + +=item B<-h, --help> + +Show help screen and exit. + +=item B<-p, --print> + +Print on stdout the result of I<NUM1> & I<NUM2>, or I<NUM1> if B<--equal> is +used + +=item B<-V, --version> + +Show version information and exit. + +=back + +=head1 DESCRIPTION + +B<aa-bw>(1) is a minimalistic helper intended to be used in execline scripts, +mainly to check (flags in) return codes. + +It simply performs a bitwise AND on its two first arguments (unless B<--equal> +is used) and returns 0 on success, 2 on error. + +Success is determined depending on which option was specified: + +=over + +=item B<--and> : Success when result is non zero + +=item B<--all> or B<--equal> : Success when result is I<NUM2> + +=back + +Note that if more then one of B<--and>, B<--all> and B<--equal> is used, the +last one will be used. + +=head1 RETURN CODES + +Return codes are somewhat unified inside B<anopa>. Odd return codes represent +fatal errors, and are detailled in B<anopa-rc>(1) + +B<aa-bw>(1) can return 2 if the test failed, as described above. diff --git a/package/modes b/package/modes index b98016e..7ce4d7f 100644 --- a/package/modes +++ b/package/modes @@ -1,3 +1,4 @@ +aa-bw 0755 aa-chroot 0755 aa-ctty 0755 aa-echo 0755 diff --git a/package/targets.mak b/package/targets.mak index b638dd3..c015f88 100644 --- a/package/targets.mak +++ b/package/targets.mak @@ -1,4 +1,5 @@ BIN_TARGETS := \ +aa-bw \ aa-chroot \ aa-ctty \ aa-echo \ @@ -34,6 +35,7 @@ aa-stage4 DOC_TARGETS := \ anopa.1 \ anopa-rc.1 \ +aa-bw.1 \ aa-chroot.1 \ aa-ctty.1 \ aa-echo.1 \ diff --git a/src/utils/aa-bw.c b/src/utils/aa-bw.c new file mode 100644 index 0000000..ec31b49 --- /dev/null +++ b/src/utils/aa-bw.c @@ -0,0 +1,131 @@ +/* + * anopa - Copyright (C) 2015-2017 Olivier Brunel + * + * aa-bw.c + * Copyright (C) 2018 Olivier Brunel <jjk@jjacky.com> + * + * This file is part of anopa. + * + * anopa 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 3 of the License, or (at your option) any later + * version. + * + * anopa 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 + * anopa. If not, see http://www.gnu.org/licenses/ + */ + +#include <getopt.h> +#include <skalibs/types.h> +#include <skalibs/bytestr.h> +#include <anopa/common.h> +#include <anopa/output.h> + +#define RC_ST_FAIL 1 << 1 + +static void +dieusage (int rc) +{ + aa_die_usage (rc, "[OPTION...] NUM1 NUM2", + " -A, --all Success if NUM1 & NUM2 == NUM2\n" + " -a, --and Success if NUM1 & NUM2 != 0; Default\n" + " -e, --equal Success if NUM1 == NUM2\n" + " -p, --print Print NUM1 & NUM2 (NUM1 w/ --equal)\n" + " -h, --help Show this help screen and exit\n" + " -V, --version Show version information and exit\n" + ); +} + +int +main (int argc, char * const argv[], char * const envp[]) +{ + PROG = "aa-bw"; + enum + { + MODE_AND = 0, + MODE_ALL, + MODE_EQUAL + } mode = MODE_AND; + unsigned int n1; + unsigned int n2; + int print = 0; + + for (;;) + { + struct option longopts[] = { + { "all", no_argument, NULL, 'A' }, + { "and", no_argument, NULL, 'a' }, + { "equal", no_argument, NULL, 'e' }, + { "help", no_argument, NULL, 'h' }, + { "print", no_argument, NULL, 'p' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, 0, 0 } + }; + int c; + + c = getopt_long (argc, argv, "AaehpV", longopts, NULL); + if (c == -1) + break; + switch (c) + { + case 'A': + mode = MODE_ALL; + break; + + case 'a': + mode = MODE_AND; + break; + + case 'e': + mode = MODE_EQUAL; + break; + + case 'h': + dieusage (RC_OK); + + case 'p': + print = 1; + break; + + case 'V': + aa_die_version (); + + default: + dieusage (RC_FATAL_USAGE); + } + } + argc -= optind; + argv += optind; + + if (argc != 2) + dieusage (RC_FATAL_USAGE); + + if (!uint0_scan (argv[0], &n1)) + aa_strerr_dief2x (RC_FATAL_USAGE, "Invalid argument: ", argv[0]); + + if (!uint0_scan (argv[1], &n2)) + aa_strerr_dief2x (RC_FATAL_USAGE, "Invalid argument: ", argv[1]); + + if (mode != MODE_EQUAL) + n1 &= n2; + + if (print) + { + char buf[UINT_FMT]; + size_t len; + + len = uint_fmt (buf, n1); + buf[len] = '\n'; + aa_bb_flush (AA_OUT, buf, len + 1); + } + + if (mode == MODE_AND) + return (n1) ? RC_OK : RC_ST_FAIL; + else + return (n1 == n2) ? RC_OK : RC_ST_FAIL; +} diff --git a/src/utils/deps-exe/aa-bw b/src/utils/deps-exe/aa-bw new file mode 100644 index 0000000..30987b4 --- /dev/null +++ b/src/utils/deps-exe/aa-bw @@ -0,0 +1,2 @@ +${LIBANOPA} +-lskarnet