#include <errno.h>
#include <sys/wait.h>
- #include <pcre.h>
+ #define PCRE2_CODE_UNIT_WIDTH 8
+ #include <pcre2.h>
#include <miniexpect.h>
mexp_h *h;
- h = mexp_spawnl ("ssh", "ssh", "host");
- switch (mexp_expect (h, regexps, ovector, ovecsize)) {
+ h = mexp_spawnl ("ssh", "ssh", "host", NULL);
+ switch (mexp_expect (h, regexps, match_data)) {
...
}
mexp_close (h);
- cc prog.c -o prog -lminiexpect -lpcre
+ cc prog.c -o prog -lminiexpect -lpcre2-8
=head1 DESCRIPTION
standards.
Miniexpect is a standalone library, except for a single dependency: it
-requires the PCRE (Perl Compatible Regular Expressions) library from
-L<http://www.pcre.org/>. The PCRE dependency is fundamental because
+requires the PCRE2 (Perl Compatible Regular Expressions) library from
+L<http://www.pcre.org/>. The PCRE2 dependency is fundamental because
we want to offer the most powerful regular expression syntax to match
-on, but more importantly because PCRE has a convenient way to detect
+on, but more importantly because PCRE2 has a convenient way to detect
partial matches which made this library very simple to implement.
This manual page documents the API. Examples of how to use the API
This creates a subprocess running the external program C<file> (the
current C<$PATH> is searched unless you give an absolute path).
-C<arg, ...> are the arguments to the program. Usually the first
-argument should be the name of the program.
+C<arg, ...> are the arguments to the program. You should terminate
+the list of arguments with C<NULL>. Usually the first argument should
+be the name of the program.
The return value is a handle (see next section).
For example, to run an ssh subprocess you could do:
- h = mexp_spawnl ("ssh", "ssh", "-l", "root", "host");
+ h = mexp_spawnl ("ssh", "ssh", "-l", "root", "host", NULL);
or to run a particular ssh binary:
- h = mexp_spawnl ("/usr/local/bin/ssh", "ssh", "-l", "root", "host");
+ h = mexp_spawnl ("/usr/local/bin/ssh", "ssh", "-l", "root", "host", NULL);
An alternative to C<mexp_spawnl> is:
=over 4
-=item C<MEXP_SPAWN_KEEP_SIGNALS>
+=item B<MEXP_SPAWN_KEEP_SIGNALS>
Do not reset signal handlers to C<SIG_DFL> in the subprocess.
B<int mexp_get_pcre_error (mexp *h);>
When C<mexp_expect> [see below] calls the PCRE function
-L<pcre_exec(3)>, it stashes the return value in the C<pcre_error>
+L<pcre2_match(3)>, it stashes the return value in the C<pcre_error>
field in the handle, and that field is returned by this method.
-There are two uses for this:
-
-=over 4
-
-=item 1.
-
If C<mexp_expect> returns C<MEXP_PCRE_ERROR>, then the actual PCRE
-error code returned by L<pcre_exec(3)> is available by calling this
-method. For a list of PCRE error codes, see L<pcreapi(3)>.
+error code returned by L<pcre2_match(3)> is available by calling this
+method. For a list of PCRE error codes, see L<pcre2api(3)>.
-=item 2.
+B<void mexp_set_debug_file (mexp *h, FILE *fp);>
-A more unusual use is if you ever need to get the captured substrings
-from your regular expression (calling L<pcre_get_substring(3)>). The
-third parameter of that function (C<stringcount>) is the value
-returned by L<pcre_exec(3)>, and so you can call it like this:
+B<FILE *mexp_get_debug_file (mexp *h);>
- pcre_get_substring (h->buffer, ovector,
- mexp_get_pcre_error (h), 1, &matched);
+Set or get the debug file of the handle. To enable debugging, pass a
+non-C<NULL> file handle, eg. C<stderr>. To disable debugging, pass
+C<NULL>. Debugging messages are printed on the file handle.
-=back
+Note that all output and input gets printed, including passwords. To
+prevent passwords from being printed, modify your code to call
+C<mexp_printf_password> instead of C<mexp_printf>.
The following fields in the handle do not have methods, but can be
accessed directly instead:
=head1 EXPECT FUNCTION
Miniexpect contains a powerful regular expression matching function
-based on L<pcre(3)>:
+based on L<pcre2(3)>:
B<int mexp_expect (mexp_h *h, const mexp_regexp *regexps,
-int *ovector, int ovecsize);>
+pcre2_match_data *match_data);>
The output of the subprocess is matched against the list of PCRE
regular expressions in C<regexps>. C<regexps> is a list of regular
struct mexp_regexp {
int r;
- const pcre *re;
- const pcre_extra *extra;
+ const pcre2_code *re;
int options;
};
typedef struct mexp_regexp mexp_regexp;
=item C<MEXP_PCRE_ERROR>
-There was a C<pcre_exec> error. C<h-E<gt>pcre_error> is set to the
+There was a C<pcre2_match> error. C<h-E<gt>pcre_error> is set to the
error code. See L<pcreapi(3)> for a list of the C<PCRE_*> error codes
and what they mean.
=item *
-C<regexps[].re>, C<regexps[].extra>, C<regexps[].options>, C<ovector>
-and C<ovecsize> are passed through to the L<pcre_exec(3)> function.
+C<regexps[].re>, C<regexps[].options> and C<match_data> are passed
+through to the L<pcre2_match(3)> function.
=item *
compiler, you can just use a local variable instead.
mexp_h *h;
- char *errptr;
+ int errcode;
int offset;
- pcre *password_re, *prompt_re;
- const int ovecsize = 12;
- int ovector[ovecsize];
+ pcre2_code *password_re, *prompt_re;
+ pcre2_match_data *match_data = pcre2_match_data_create (4, NULL);
- password_re = pcre_compile ("assword", 0, &errptr, &offset, NULL);
- prompt_re = pcre_compile ("[$#] ", 0, &errptr, &offset, NULL);
+ password_re = pcre2_compile ("assword", PCRE2_ZERO_TERMINATED,
+ 0, &errcode, &offset, NULL);
+ prompt_re = pcre2_compile ("[$#] ", PCRE2_ZERO_TERMINATED,
+ 0, &errcode, &offset, NULL);
switch (mexp_expect (h,
(mexp_regexp[]) {
{ 100, .re = password_re },
{ 101, .re = prompt_re },
{ 0 },
- }, ovector, ovecsize)) {
+ }, match_data)) {
case 100:
/* here you would send a password */
break;
B<int mexp_printf (mexp_h *h, const char *fs, ...);>
+B<int mexp_printf_password (mexp_h *h, const char *fs, ...);>
+
This returns the number of bytes, if the whole message was written OK.
If there was an error, -1 is returned and the error is available in
C<errno>.
mexp_printf (h, "exit\n");
+=item *
+
+C<mexp_printf_password> works identically to C<mexp_printf> except
+that the output is I<not> sent to the debugging file if debugging is
+enabled. As the name suggests, use this for passwords so that they
+don't appear in debugging output.
+
=back
B<int mexp_send_interrupt (mexp_h *h);>
=head1 SEE ALSO
-L<pcre(3)>,
-L<pcre_exec(3)>,
-L<pcreapi(3)>,
+L<pcre2(3)>,
+L<pcre2_match(3)>,
+L<pcre2api(3)>,
L<waitpid(2)>,
L<system(3)>.
=head1 COPYRIGHT
-Copyright (C) 2014 Red Hat Inc.
+Copyright (C) 2014-2022 Red Hat Inc.