1 #include <ctype.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <sys/mman.h>
5 #include <fcntl.h>
6 #include <string.h>
7 #include <termios.h>
8 #include <unistd.h>
9
10 struct {
11 char key;
12 char *chars;
13 } map[] = {
14 { '1', "_ -1?!,.:;\"'<=>()_" },
15 { '2', "Cabc2ABC" },
16 { '3', "Fdef3DEF" },
17 { '4', "Ighi4GHI" },
18 { '5', "Ljkl5JKL" },
19 { '6', "Omno6MNO" },
20 { '7', "Spqrs7PQRS" },
21 { '8', "Vtuv8TUV" },
22 { '9', "Zwxyz9WXYZ" },
23 { '0', "*+&0@/#*" },
24 };
25
next_char(char key,char current)26 char next_char(char key, char current)
27 {
28 int i;
29 char *next;
30 for(i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
31 if(key == map[i].key) {
32 next = strchr(map[i].chars, current);
33 if(next && next[1])
34 return next[1];
35 return map[i].chars[1];
36 }
37 }
38 return key;
39 }
40
prev_char(char key,char current)41 char prev_char(char key, char current)
42 {
43 int i;
44 char *next;
45 for(i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
46 if(key == map[i].key) {
47 next = strchr(map[i].chars+1, current);
48 if(next && next[-1])
49 return next[-1];
50 return map[i].chars[1];
51 }
52 }
53 return key;
54 }
55
readtty_main(int argc,char * argv[])56 int readtty_main(int argc, char *argv[])
57 {
58 int c;
59 //int flags;
60 char buf[1];
61 int res;
62 struct termios ttyarg;
63 struct termios savedttyarg;
64 int nonblock = 0;
65 int timeout = 0;
66 int flush = 0;
67 int phone = 0;
68 char *accept = NULL;
69 char *rejectstring = NULL;
70 char last_char_in = 0;
71 char current_char = 0;
72 char *exit_string = NULL;
73 int exit_match = 0;
74
75 do {
76 c = getopt(argc, argv, "nt:fa:r:pe:");
77 if (c == EOF)
78 break;
79 switch (c) {
80 case 't':
81 timeout = atoi(optarg);
82 break;
83 case 'n':
84 nonblock = 1;
85 break;
86 case 'f':
87 flush = 1;
88 break;
89 case 'a':
90 accept = optarg;
91 break;
92 case 'r':
93 rejectstring = optarg;
94 break;
95 case 'p':
96 phone = 1;
97 break;
98 case 'e':
99 exit_string = optarg;
100 break;
101 case '?':
102 fprintf(stderr, "%s: invalid option -%c\n",
103 argv[0], optopt);
104 exit(1);
105 }
106 } while (1);
107
108 if(flush)
109 tcflush(STDIN_FILENO, TCIFLUSH);
110 ioctl(STDIN_FILENO, TCGETS , &savedttyarg) ; /* set changed tty arguments */
111 ttyarg = savedttyarg;
112 ttyarg.c_cc[VMIN] = (timeout > 0 || nonblock) ? 0 : 1; /* minimum of 0 chars */
113 ttyarg.c_cc[VTIME] = timeout; /* wait max 15/10 sec */
114 ttyarg.c_iflag = BRKINT | ICRNL;
115 ttyarg.c_lflag &= ~(ECHO | ICANON);
116 ioctl(STDIN_FILENO, TCSETS , &ttyarg);
117
118 while (1) {
119 res = read(STDIN_FILENO, buf, 1);
120 if(res <= 0) {
121 if(phone) {
122 if(current_char) {
123 write(STDERR_FILENO, ¤t_char, 1);
124 write(STDOUT_FILENO, ¤t_char, 1);
125 if(exit_string && current_char == exit_string[exit_match]) {
126 exit_match++;
127 if(exit_string[exit_match] == '\0')
128 break;
129 }
130 else
131 exit_match = 0;
132 current_char = 0;
133 }
134 continue;
135 }
136 break;
137 }
138 if(accept && strchr(accept, buf[0]) == NULL) {
139 if(rejectstring) {
140 write(STDOUT_FILENO, rejectstring, strlen(rejectstring));
141 break;
142 }
143 if(flush)
144 tcflush(STDIN_FILENO, TCIFLUSH);
145 continue;
146 }
147 if(phone) {
148 //if(!isprint(buf[0])) {
149 // fprintf(stderr, "got unprintable character 0x%x\n", buf[0]);
150 //}
151 if(buf[0] == '\0') {
152 if(current_char) {
153 current_char = prev_char(last_char_in, current_char);
154 write(STDERR_FILENO, ¤t_char, 1);
155 write(STDERR_FILENO, "\b", 1);
156 }
157 continue;
158 }
159 if(current_char && buf[0] != last_char_in) {
160 write(STDERR_FILENO, ¤t_char, 1);
161 write(STDOUT_FILENO, ¤t_char, 1);
162 if(exit_string && current_char == exit_string[exit_match]) {
163 exit_match++;
164 if(exit_string[exit_match] == '\0')
165 break;
166 }
167 else
168 exit_match = 0;
169 current_char = 0;
170 }
171 last_char_in = buf[0];
172 current_char = next_char(last_char_in, current_char);
173 write(STDERR_FILENO, ¤t_char, 1);
174 write(STDERR_FILENO, "\b", 1);
175 continue;
176 }
177 write(STDOUT_FILENO, buf, 1);
178 break;
179 }
180 ioctl(STDIN_FILENO, TCSETS , &savedttyarg) ; /* set changed tty arguments */
181
182 return 0;
183 }
184