• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &current_char, 1);
124                     write(STDOUT_FILENO, &current_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, &current_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, &current_char, 1);
161                 write(STDOUT_FILENO, &current_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, &current_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