Cleaned up message_id().
[mmh] / sbr / getans.c
1
2 /*
3  * getans.c -- get an answer from the user and return a string array
4  *
5  * This code is Copyright (c) 2002, by the authors of nmh.  See the
6  * COPYRIGHT file in the root directory of the nmh distribution for
7  * complete copyright information.
8  */
9
10 #include <h/mh.h>
11 #include <h/signals.h>
12 #include <setjmp.h>
13 #include <signal.h>
14 #include <errno.h>
15
16 static char ansbuf[BUFSIZ];
17 static sigjmp_buf sigenv;
18
19 /*
20  * static prototypes
21  */
22 static void intrser (int);
23
24
25 char **
26 getans (char *prompt, struct swit *ansp)
27 {
28     int i;
29     SIGNAL_HANDLER istat = NULL;
30     char *cp, **cpp;
31
32     if (!(sigsetjmp(sigenv, 1))) {
33         istat = SIGNAL (SIGINT, intrser);
34     } else {
35         SIGNAL (SIGINT, istat);
36         return NULL;
37     }
38
39     for (;;) {
40         printf ("%s", prompt);
41         fflush (stdout);
42         cp = ansbuf;
43         while ((i = getchar ()) != '\n') {
44             if (i == EOF) {
45                 /*
46                  * If we get an EOF, return
47                  */
48                 if (feof(stdin))
49                     siglongjmp (sigenv, 1);
50
51                 /*
52                  * For errors, if we get an EINTR that means that we got
53                  * a signal and we should retry.  If we get another error,
54                  * then just return.
55                  */
56
57                 else if (ferror(stdin)) {
58                     if (errno == EINTR) {
59                         clearerr(stdin);
60                         continue;
61                     }
62                     fprintf(stderr, "\nError %s during read\n",
63                             strerror(errno));
64                     siglongjmp (sigenv, 1);
65                 } else {
66                     /*
67                      * Just for completeness's sake ...
68                      */
69
70                     fprintf(stderr, "\nUnknown problem in getchar()\n");
71                     siglongjmp (sigenv, 1);
72                 }
73             }
74             if (cp < &ansbuf[sizeof ansbuf - 1])
75                 *cp++ = i;
76         }
77         *cp = '\0';
78         if (ansbuf[0] == '?' || cp == ansbuf) {
79             printf ("Options are:\n");
80             print_sw (ALL, ansp, "", stdout);
81             continue;
82         }
83         cpp = brkstring (ansbuf, " ", NULL);
84         switch (smatch (*cpp, ansp)) {
85             case AMBIGSW: 
86                 ambigsw (*cpp, ansp);
87                 continue;
88             case UNKWNSW: 
89                 printf (" -%s unknown. Hit <CR> for help.\n", *cpp);
90                 continue;
91             default: 
92                 SIGNAL (SIGINT, istat);
93                 return cpp;
94         }
95     }
96 }
97
98
99 static void
100 intrser (int i)
101 {
102     NMH_UNUSED (i);
103
104     /*
105      * should this be siglongjmp?
106      */
107     siglongjmp (sigenv, 1);
108 }