Home | History | Annotate | Download | only in toolbox
      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 
     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 
     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 
     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