00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #if defined(HAVE_CONFIG_H)
00034 #include <config.h>
00035 #endif
00036
00037 #include <stdarg.h>
00038 #include <string.h>
00039 #include <unistd.h>
00040 #include <fcntl.h>
00041 #include <sys/types.h>
00042
00043 #include "rdd.h"
00044 #include "rdd_internals.h"
00045 #include "error.h"
00046
00047 #define MAX_WRITEBUF 256
00048 #define MAX_LINE 80
00049
00050 static int console_fd = -1;
00051 static int quiet = 0;
00052
00053 void
00054 rdd_set_quiet(int q)
00055 {
00056 quiet = q;
00057 }
00058
00059
00060 static void
00061 cons_write(char *buf, unsigned buf_size)
00062 {
00063 #if defined(RDD_CONSOLE)
00064 int n;
00065
00066 if (console_fd < 0) return;
00067
00068 while (buf_size > 0) {
00069 if ((n = write(console_fd, buf, buf_size)) < 0) {
00070 (void) close(console_fd);
00071 console_fd = -1;
00072 unix_error("cannot write to tty");
00073 }
00074 buf += n;
00075 buf_size -= n;
00076 }
00077 #endif
00078 }
00079
00080 void
00081 rdd_cons_open(void)
00082 {
00083 #if defined(RDD_CONSOLE)
00084 if ((console_fd = open("/dev/tty", O_RDWR)) < 0) {
00085 unix_error("cannot open terminal");
00086 }
00087 #endif
00088 }
00089
00090 void
00091 rdd_cons_close(void)
00092 {
00093 #if defined(RDD_CONSOLE)
00094 if (console_fd < 0) return;
00095
00096 (void) close(console_fd);
00097 console_fd = -1;
00098 #endif
00099 }
00100
00101
00102
00103
00104 static int
00105 rdd_vask(char *fmt, va_list ap)
00106 {
00107 char line[MAX_LINE];
00108 int answer = RDD_NO;
00109 ssize_t n;
00110
00111 while (1) {
00112 rdd_cons_vprintf(fmt, ap);
00113 rdd_cons_printf(" ");
00114
00115 n = read(console_fd, line, sizeof line);
00116 if (n < 0) {
00117 unix_error("cannot read from terminal");
00118 } else if (n == 0) {
00119 error("terminal closed?");
00120 }
00121
00122 if (line[n-1] != '\n') {
00123 error("line too long");
00124 }
00125 line[n-1] = '\000';
00126
00127 if (strcmp(line, "yes") == 0 || strcmp(line, "YES") == 0) {
00128 answer = RDD_YES;
00129 break;
00130 }
00131 if (strcmp(line, "no") == 0 || strcmp(line, "NO") == 0) {
00132 answer = RDD_NO;
00133 break;
00134 }
00135 rdd_cons_printf("Please answer yes or no.\n");
00136 }
00137
00138 return answer;
00139 }
00140
00141 int
00142 rdd_ask(char *fmt, ...)
00143 {
00144 va_list ap;
00145 int rc;
00146
00147 va_start(ap, fmt);
00148 rc = rdd_vask(fmt, ap);
00149 va_end(ap);
00150 return rc;
00151 }
00152
00153 void
00154 rdd_quit_if(int quit_answer, char *fmt, ...)
00155 {
00156 va_list ap;
00157
00158 va_start(ap, fmt);
00159 if (!quiet && rdd_vask(fmt, ap) == quit_answer) {
00160 exit(EXIT_FAILURE);
00161 }
00162 va_end(ap);
00163 }
00164
00168 void
00169 rdd_cons_vprintf(char *fmt, va_list ap)
00170 {
00171 #if defined(RDD_CONSOLE)
00172 char promptbuf[MAX_WRITEBUF+1];
00173
00174 if (console_fd < 0) {
00175 return;
00176 }
00177
00178 vsnprintf(promptbuf, MAX_WRITEBUF, fmt, ap);
00179 promptbuf[MAX_WRITEBUF] = '\000';
00180 cons_write(promptbuf, strlen(promptbuf));
00181 #endif
00182 }
00183
00184 void
00185 rdd_cons_printf(char *fmt, ...)
00186 {
00187 #if defined(RDD_CONSOLE)
00188 va_list ap;
00189
00190 va_start(ap, fmt);
00191 rdd_cons_vprintf(fmt, ap);
00192 va_end(ap);
00193 #endif
00194 }