85826a0603e5260783ecf8647cc561403501a0da
[miniexpect.git] / miniexpect.c
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 #include <config.h>
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <signal.h>
29 #include <poll.h>
30 #include <errno.h>
31 #include <termios.h>
32 #include <time.h>
33 #include <assert.h>
34 #include <sys/types.h>
35 #include <sys/wait.h>
36 #include <sys/time.h>
37
38 #include <pcre.h>
39
40 /* RHEL 6 pcre did not define PCRE_PARTIAL_SOFT.  However PCRE_PARTIAL
41  * is a synonym so use that.
42  */
43 #ifndef PCRE_PARTIAL_SOFT
44 #define PCRE_PARTIAL_SOFT PCRE_PARTIAL
45 #endif
46
47 #include "miniexpect.h"
48
49 static void debug_buffer (FILE *, const char *);
50
51 static mexp_h *
52 create_handle (void)
53 {
54   mexp_h *h = malloc (sizeof *h);
55   if (h == NULL)
56     return NULL;
57
58   /* Initialize the fields to default values. */
59   h->fd = -1;
60   h->pid = 0;
61   h->timeout = 60000;
62   h->read_size = 1024;
63   h->pcre_error = 0;
64   h->buffer = NULL;
65   h->len = h->alloc = 0;
66   h->next_match = -1;
67   h->debug_fp = NULL;
68   h->user1 = h->user2 = h->user3 = NULL;
69
70   return h;
71 }
72
73 static void
74 clear_buffer (mexp_h *h)
75 {
76   free (h->buffer);
77   h->buffer = NULL;
78   h->alloc = h->len = 0;
79   h->next_match = -1;
80 }
81
82 int
83 mexp_close (mexp_h *h)
84 {
85   int status = 0;
86
87   free (h->buffer);
88
89   if (h->fd >= 0)
90     close (h->fd);
91   if (h->pid > 0) {
92     if (waitpid (h->pid, &status, 0) == -1)
93       return -1;
94   }
95
96   free (h);
97
98   return status;
99 }
100
101 mexp_h *
102 mexp_spawnlf (unsigned flags, const char *file, const char *arg, ...)
103 {
104   char **argv, **new_argv;
105   size_t i;
106   va_list args;
107   mexp_h *h;
108
109   argv = malloc (sizeof (char *));
110   if (argv == NULL)
111     return NULL;
112   argv[0] = (char *) arg;
113
114   va_start (args, arg);
115   for (i = 1; arg != NULL; ++i) {
116     arg = va_arg (args, const char *);
117     new_argv = realloc (argv, sizeof (char *) * (i+1));
118     if (new_argv == NULL) {
119       free (argv);
120       va_end (args);
121       return NULL;
122     }
123     argv = new_argv;
124     argv[i] = (char *) arg;
125   }
126
127   h = mexp_spawnvf (flags, file, argv);
128   free (argv);
129   va_end (args);
130   return h;
131 }
132
133 mexp_h *
134 mexp_spawnvf (unsigned flags, const char *file, char **argv)
135 {
136   mexp_h *h = NULL;
137   int fd = -1;
138   int err;
139   char slave[1024];
140   pid_t pid = 0;
141
142   fd = posix_openpt (O_RDWR|O_NOCTTY);
143   if (fd == -1)
144     goto error;
145
146   if (grantpt (fd) == -1)
147     goto error;
148
149   if (unlockpt (fd) == -1)
150     goto error;
151
152   /* Get the slave pty name now, but don't open it in the parent. */
153   if (ptsname_r (fd, slave, sizeof slave) != 0)
154     goto error;
155
156   /* Create the handle last before we fork. */
157   h = create_handle ();
158   if (h == NULL)
159     goto error;
160
161   pid = fork ();
162   if (pid == -1)
163     goto error;
164
165   if (pid == 0) {               /* Child. */
166     int slave_fd;
167
168     if (!(flags & MEXP_SPAWN_KEEP_SIGNALS)) {
169       struct sigaction sa;
170       int i;
171
172       /* Remove all signal handlers.  See the justification here:
173        * https://www.redhat.com/archives/libvir-list/2008-August/msg00303.html
174        * We don't mask signal handlers yet, so this isn't completely
175        * race-free, but better than not doing it at all.
176        */
177       memset (&sa, 0, sizeof sa);
178       sa.sa_handler = SIG_DFL;
179       sa.sa_flags = 0;
180       sigemptyset (&sa.sa_mask);
181       for (i = 1; i < NSIG; ++i)
182         sigaction (i, &sa, NULL);
183     }
184
185     setsid ();
186
187     /* Open the slave side of the pty.  We must do this in the child
188      * after setsid so it becomes our controlling tty.
189      */
190     slave_fd = open (slave, O_RDWR);
191     if (slave_fd == -1)
192       goto error;
193
194     if (!(flags & MEXP_SPAWN_COOKED_MODE)) {
195       struct termios termios;
196
197       /* Set raw mode. */
198       tcgetattr (slave_fd, &termios);
199       cfmakeraw (&termios);
200       tcsetattr (slave_fd, TCSANOW, &termios);
201     }
202
203     /* Set up stdin, stdout, stderr to point to the pty. */
204     dup2 (slave_fd, 0);
205     dup2 (slave_fd, 1);
206     dup2 (slave_fd, 2);
207     close (slave_fd);
208
209     /* Close the master side of the pty - do this late to avoid a
210      * kernel bug, see sshpass source code.
211      */
212     close (fd);
213
214     if (!(flags & MEXP_SPAWN_KEEP_FDS)) {
215       int i, max_fd;
216
217       /* Close all other file descriptors.  This ensures that we don't
218        * hold open (eg) pipes from the parent process.
219        */
220       max_fd = sysconf (_SC_OPEN_MAX);
221       if (max_fd == -1)
222         max_fd = 1024;
223       if (max_fd > 65536)
224         max_fd = 65536;      /* bound the amount of work we do here */
225       for (i = 3; i < max_fd; ++i)
226         close (i);
227     }
228
229     /* Run the subprocess. */
230     execvp (file, argv);
231     perror (file);
232     _exit (EXIT_FAILURE);
233   }
234
235   /* Parent. */
236
237   h->fd = fd;
238   h->pid = pid;
239   return h;
240
241  error:
242   err = errno;
243   if (fd >= 0)
244     close (fd);
245   if (pid > 0)
246     waitpid (pid, NULL, 0);
247   if (h != NULL)
248     mexp_close (h);
249   errno = err;
250   return NULL;
251 }
252
253 enum mexp_status
254 mexp_expect (mexp_h *h, const mexp_regexp *regexps, int *ovector, int ovecsize)
255 {
256   time_t start_t, now_t;
257   int timeout;
258   struct pollfd pfds[1];
259   int r;
260   ssize_t rs;
261
262   time (&start_t);
263
264   if (h->next_match == -1) {
265     /* Fully clear the buffer, then read. */
266     clear_buffer (h);
267   } else {
268     /* See the comment in the manual about h->next_match.  We have
269      * some data remaining in the buffer, so begin by matching that.
270      */
271     memmove (&h->buffer[0], &h->buffer[h->next_match], h->len - h->next_match);
272     h->len -= h->next_match;
273     h->buffer[h->len] = '\0';
274     h->next_match = -1;
275     goto try_match;
276   }
277
278   for (;;) {
279     /* If we've got a timeout then work out how many seconds are left.
280      * Timeout == 0 is not particularly well-defined, but it probably
281      * means "return immediately if there's no data to be read".
282      */
283     if (h->timeout >= 0) {
284       time (&now_t);
285       timeout = h->timeout - ((now_t - start_t) * 1000);
286       if (timeout < 0)
287         timeout = 0;
288     }
289     else
290       timeout = 0;
291
292     pfds[0].fd = h->fd;
293     pfds[0].events = POLLIN;
294     pfds[0].revents = 0;
295     r = poll (pfds, 1, timeout);
296     if (h->debug_fp)
297       fprintf (h->debug_fp, "DEBUG: poll returned %d\n", r);
298     if (r == -1)
299       return MEXP_ERROR;
300
301     if (r == 0)
302       return MEXP_TIMEOUT;
303
304     /* Otherwise we expect there is something to read from the file
305      * descriptor.
306      */
307     if (h->alloc - h->len <= h->read_size) {
308       char *new_buffer;
309       /* +1 here allows us to store \0 after the data read */
310       new_buffer = realloc (h->buffer, h->alloc + h->read_size + 1);
311       if (new_buffer == NULL)
312         return MEXP_ERROR;
313       h->buffer = new_buffer;
314       h->alloc += h->read_size;
315     }
316     rs = read (h->fd, h->buffer + h->len, h->read_size);
317     if (h->debug_fp)
318       fprintf (h->debug_fp, "DEBUG: read returned %zd\n", rs);
319     if (rs == -1) {
320       /* Annoyingly on Linux (I'm fairly sure this is a bug) if the
321        * writer closes the connection, the entire pty is destroyed,
322        * and read returns -1 / EIO.  Handle that special case here.
323        */
324       if (errno == EIO)
325         return MEXP_EOF;
326       return MEXP_ERROR;
327     }
328     if (rs == 0)
329       return MEXP_EOF;
330
331     /* We read something. */
332     h->len += rs;
333     h->buffer[h->len] = '\0';
334     if (h->debug_fp) {
335       fprintf (h->debug_fp, "DEBUG: read %zd bytes from pty\n", rs);
336       fprintf (h->debug_fp, "DEBUG: buffer content: ");
337       debug_buffer (h->debug_fp, h->buffer);
338       fprintf (h->debug_fp, "\n");
339     }
340
341   try_match:
342     /* See if there is a full or partial match against any regexp. */
343     if (regexps) {
344       size_t i;
345       int can_clear_buffer = 1;
346
347       assert (h->buffer != NULL);
348
349       for (i = 0; regexps[i].r > 0; ++i) {
350         const int options = regexps[i].options | PCRE_PARTIAL_SOFT;
351
352         r = pcre_exec (regexps[i].re, regexps[i].extra,
353                        h->buffer, (int)h->len, 0,
354                        options,
355                        ovector, ovecsize);
356         h->pcre_error = r;
357
358         if (r >= 0) {
359           /* A full match. */
360           if (ovector != NULL && ovecsize >= 1 && ovector[1] >= 0)
361             h->next_match = ovector[1];
362           else
363             h->next_match = -1;
364           if (h->debug_fp)
365             fprintf (h->debug_fp, "DEBUG: next_match at buffer offset %zu\n",
366                      h->next_match);
367           return regexps[i].r;
368         }
369
370         else if (r == PCRE_ERROR_NOMATCH) {
371           /* No match at all. */
372           /* (nothing here) */
373         }
374
375         else if (r == PCRE_ERROR_PARTIAL) {
376           /* Partial match.  Keep the buffer and keep reading. */
377           can_clear_buffer = 0;
378         }
379
380         else {
381           /* An actual PCRE error. */
382           return MEXP_PCRE_ERROR;
383         }
384       }
385
386       /* If none of the regular expressions matched (not partially)
387        * then we can clear the buffer.  This is an optimization.
388        */
389       if (can_clear_buffer)
390         clear_buffer (h);
391
392     } /* if (regexps) */
393   }
394 }
395
396 static int mexp_vprintf (mexp_h *h, int password, const char *fs, va_list args)
397   __attribute__((format(printf,3,0)));
398
399 static int
400 mexp_vprintf (mexp_h *h, int password, const char *fs, va_list args)
401 {
402   char *msg;
403   int len;
404   size_t n;
405   ssize_t r;
406   char *p;
407
408   len = vasprintf (&msg, fs, args);
409
410   if (len < 0)
411     return -1;
412
413   if (h->debug_fp) {
414     if (!password) {
415       fprintf (h->debug_fp, "DEBUG: writing: ");
416       debug_buffer (h->debug_fp, msg);
417       fprintf (h->debug_fp, "\n");
418     }
419     else
420       fprintf (h->debug_fp, "DEBUG: writing the password\n");
421   }
422
423   n = len;
424   p = msg;
425   while (n > 0) {
426     r = write (h->fd, p, n);
427     if (r == -1) {
428       free (msg);
429       return -1;
430     }
431     n -= r;
432     p += r;
433   }
434
435   free (msg);
436   return len;
437 }
438
439 int
440 mexp_printf (mexp_h *h, const char *fs, ...)
441 {
442   int r;
443   va_list args;
444
445   va_start (args, fs);
446   r = mexp_vprintf (h, 0, fs, args);
447   va_end (args);
448   return r;
449 }
450
451 int
452 mexp_printf_password (mexp_h *h, const char *fs, ...)
453 {
454   int r;
455   va_list args;
456
457   va_start (args, fs);
458   r = mexp_vprintf (h, 1, fs, args);
459   va_end (args);
460   return r;
461 }
462
463 int
464 mexp_send_interrupt (mexp_h *h)
465 {
466   return write (h->fd, "\003", 1);
467 }
468
469 /* Print escaped buffer to fp. */
470 static void
471 debug_buffer (FILE *fp, const char *buf)
472 {
473   while (*buf) {
474     if (isprint (*buf))
475       fputc (*buf, fp);
476     else {
477       switch (*buf) {
478       case '\0': fputs ("\\0", fp); break;
479       case '\a': fputs ("\\a", fp); break;
480       case '\b': fputs ("\\b", fp); break;
481       case '\f': fputs ("\\f", fp); break;
482       case '\n': fputs ("\\n", fp); break;
483       case '\r': fputs ("\\r", fp); break;
484       case '\t': fputs ("\\t", fp); break;
485       case '\v': fputs ("\\v", fp); break;
486       default:
487         fprintf (fp, "\\x%x", (unsigned char) *buf);
488       }
489     }
490     buf++;
491   }
492 }