ba3607aa58b1e28e81774285695a8976747d6d10
[miniexpect.git] / miniexpect.h
1 /* miniexpect
2  * Copyright (C) 2014 Red Hat Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #ifndef MINIEXPECT_H_
20 #define MINIEXPECT_H_
21
22 #include <unistd.h>
23
24 #include <pcre.h>
25
26 /* This handle is created per subprocess that is spawned. */
27 struct mexp_h {
28   int fd;                       /* File descriptor pointing to pty. */
29   pid_t pid;                    /* Subprocess PID. */
30
31   /* Timeout (milliseconds, 1/1000th seconds).  The caller may set
32    * this before calling mexp_expect.  Set it to -1 to mean no
33    * timeout.  The default is 60000 (= 60 seconds).
34    */
35   int timeout;
36
37   /* The read buffer is allocated by the library when mexp_expect is
38    * called.  It is available so you can examine the buffer to see
39    * what part of the regexp matched.  Note this buffer does not
40    * contain the full input from the process, but it will contain at
41    * least the part matched by the regular expression (and maybe some
42    * more).
43    */
44   char *buffer;                 /* Read buffer. */
45   size_t len;                   /* Length of data in the buffer. */
46   size_t alloc;                 /* Allocated size of the buffer. */
47
48   /* The caller may set this to set the size (in bytes) for reads from
49    * the subprocess.  The default is 1024.
50    */
51   size_t read_size;
52
53   /* If mexp_expect returns MEXP_PCRE_ERROR, then the actual PCRE
54    * error code is returned here.  See pcre_exec(3) for details.
55    */
56   int pcre_error;
57
58   /* Opaque pointers for use of the caller.  The library will not
59    * touch these.
60    */
61   void *user1;
62   void *user2;
63   void *user3;
64 };
65 typedef struct mexp_h mexp_h;
66
67 /* Spawn a subprocess.
68  *
69  * If successful it returns a handle.  If it fails, it returns NULL
70  * and sets errno.
71  */
72 extern mexp_h *mexp_spawnv (const char *file, char **argv);
73
74 /* Same as mexp_spawnv, but it uses a NULL-terminated variable length
75  * list of arguments.
76  */
77 extern mexp_h *mexp_spawnl (const char *file, const char *arg, ...);
78
79 /* Close the handle and clean up the subprocess.
80  *
81  * This returns:
82  *   0:   successful close, subprocess exited cleanly.
83  *   -1:  error in system call, see errno.
84  *   > 0: exit status of subprocess if it didn't exit cleanly.  Use
85  *        WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG etc macros to
86  *        examine this.
87  *
88  * Notes:
89  *
90  * - Even in the error cases, the handle is always closed and
91  *   freed by this call.
92  *
93  * - It is normal for the kernel to send SIGHUP to the subprocess.
94  *   If the subprocess doesn't catch the SIGHUP, then it will die
95  *   (WIFSIGNALED (status) && WTERMSIG (status) == SIGHUP).  This
96  *   case should not necessarily be considered an error.
97  */
98 extern int mexp_close (mexp_h *h);
99
100 /* The list of regular expressions passed to mexp_expect. */
101 struct mexp_regexp {
102   int r;                        /* The returned value from mexp_expect
103                                  * if this regular expression matches.
104                                  * MUST be > 0.
105                                  */
106   const pcre *re;               /* The compiled regular expression. */
107   const pcre_extra *extra;      /* See pcre_exec. */
108   int options;                  /* See pcre_exec. */
109 };
110 typedef struct mexp_regexp mexp_regexp;
111
112 enum mexp_status {
113   MEXP_EOF        = 0,
114   MEXP_TIMEOUT    = -1,
115   MEXP_ERROR      = -2,
116   MEXP_PCRE_ERROR = -3,
117 };
118
119 /* Expect some output from the subprocess.  Match the output against
120  * the PCRE regular expression(s) in the list, and return which one
121  * matched.
122  *
123  * See example-sshpass.c for an example of how to pass in regular
124  * expressions.
125  *
126  * This can return:
127  *
128  *   MEXP_TIMEOUT:
129  *     No input matched before the timeout (mexp_h->timeout) was reached.
130  *   MEXP_EOF:
131  *     The subprocess closed the connection.
132  *   MEXP_ERROR:
133  *     There was a system call error (eg. from the read call).  See errno.
134  *   MEXP_PCRE_ERROR
135  *     There was a pcre_exec error.  h->pcre_error is set to the error code
136  *     (see pcreapi(3) for a list of PCRE_* error codes and what they mean).
137  *
138  * Notes:
139  *
140  * - 'regexps' may be NULL or an empty list, which means we don't
141  *   match against a regular expression.  This is useful if you just
142  *   want to wait for EOF or timeout.
143  *
144  * - 'regexps[].re', 'regexps[].extra', 'regexps[].options', 'ovector'
145  *   and 'ovecsize' are passed through to the pcre_exec function.
146  */
147 extern int mexp_expect (mexp_h *h, const mexp_regexp *regexps,
148                         int *ovector, int ovecsize);
149
150 /* This is a convenience function for writing something (eg. a
151  * password or command) to the subprocess.  You could do this by
152  * writing directly to 'h->fd', but this function does all the error
153  * checking for you.
154  *
155  * Returns the number of bytes if the whole message was written OK
156  * (partial writes are not possible with this function), or -1 if
157  * there was an error (check errno).
158  */
159 extern int mexp_printf (mexp_h *h, const char *fs, ...)
160   __attribute__((format(printf,2,3)));
161
162 #endif /* MINIEXPECT_H_ */