diff options
Diffstat (limited to 'src/getkey.c')
-rw-r--r-- | src/getkey.c | 220 |
1 files changed, 122 insertions, 98 deletions
diff --git a/src/getkey.c b/src/getkey.c index 0aa60921..62833b7d 100644 --- a/src/getkey.c +++ b/src/getkey.c @@ -1,98 +1,122 @@ - -#include <ctype.h> -#include <errno.h> -#include <signal.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <termios.h> -#include <unistd.h> -#include <sys/poll.h> - -/* A very simple keygrabber. */ - -struct termios tp; - -void reset_term(int x) { - tcsetattr(0,TCSANOW,&tp); - exit(x); -} - -int main(int argc, char **argv) { - char foo[2]; - char *list = NULL; - char *waitmessage = NULL; - char *waitprint, *waitsprint; - int waitseconds=0; - int alarmlen=0; - int tp_if,tp_of,tp_lf; - int x, r; - struct pollfd ufds; /* only one, no need for an array... */ - - for (++argv, --argc; argc; argc--, argv++) { - if (argv[0][0]=='-') { - if (argv[0][1]=='c') { - argc--; argv++; - waitseconds = atoi(argv[0]); - } else if (argv[0][1]=='m') { - argc--; argv++; - waitmessage=argv[0]; - } else if (isdigit(argv[0][1])) { - waitseconds = atoi(argv[0]); - } - } else { - list = argv[0]; - for (x=0;list[x];x++) list[x]=toupper(list[x]); - } - } - if (waitseconds) { - alarmlen = waitseconds; - } - foo[0]=foo[1]='\0'; - - signal(SIGTERM,reset_term); - alarm(alarmlen); - signal(SIGALRM,reset_term); - - tcgetattr(0,&tp); - tp_if=tp.c_iflag; - tp_of=tp.c_oflag; - tp_lf=tp.c_lflag; - tp.c_iflag=0; - tp.c_oflag &= ~OPOST; - tp.c_lflag &= ~(ISIG | ICANON); - tcsetattr(0,TCSANOW,&tp); - tp.c_iflag=tp_if; - tp.c_oflag=tp_of; - tp.c_lflag=tp_lf; - - ufds.events = POLLIN; - ufds.fd = 0; - - if (waitseconds && waitmessage) { - waitprint = alloca (strlen(waitmessage)+15); /* long enough */ - waitprint[0] = '\r'; - waitsprint = waitprint + 1; - } - - while (1) { - if (waitseconds) { - sprintf (waitsprint, waitmessage, waitseconds); - write (1, waitprint, strlen(waitprint)); - } - r = poll(&ufds, 1, alarmlen ? 1000 : -1); - if (r == 0) { - /* we have waited a whole second with no keystroke... */ - waitseconds--; - } - if (r > 0) { - read(0,foo,1); - foo[0]=toupper(foo[0]); - /* Die if we get a control-c or control-d */ - if (foo[0]==3 || foo[0]==4) reset_term(1); - if ((!list) || strstr(list,foo)) { - reset_term(0); - } - } - } -} +/*
+ * getkey
+ *
+ * A very simple keygrabber.
+ *
+ */
+#include <ctype.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include "popt.h"
+
+struct termios tp;
+
+void reset_term(int x) {
+ tcsetattr(0,TCSANOW,&tp);
+ exit(x);
+}
+
+int main(int argc, char **argv) {
+ char foo[2];
+ char list[100]; /* should be enough */
+ char *waitmessage = NULL;
+ char *waitprint, *waitsprint;
+ const char *fooptr;
+ int waitseconds=0;
+ int alarmlen=0;
+ int ignore_control=0;
+ int tp_if,tp_of,tp_lf;
+ int x, r;
+ struct pollfd ufds; /* only one, no need for an array... */
+ poptContext context;
+ struct poptOption options[] = {
+ { "wait", 'c', POPT_ARG_INT, &waitseconds, 0, "Number of seconds to wait for keypress", NULL },
+ /* { "message", 'm', POPT_ARG_STRING, &waitmessage, 0, "Message to print out while waiting for string", "NOTE: argument must have a \"%d\" in it so the number of seconds\nleft until getkey times out can be printed" },*/
+ { "message", 'm', POPT_ARG_STRING, &waitmessage, 0, "Message to print out while waiting for string\nNOTE: message must have a \"%d\" in it, to hold the number of seconds left to wait", NULL },
+ { "ignore-control-chars", 'i', POPT_ARG_NONE, &ignore_control, 0, "Ignore Control-C and Control-D", NULL },
+ POPT_AUTOHELP
+ POPT_TABLEEND
+ };
+
+ strcpy(list, "");
+ context = poptGetContext("getkey", argc, argv, options,
+ POPT_CONTEXT_POSIXMEHARDER);
+ poptSetOtherOptionHelp(context, "[keys]");
+
+ r = poptGetNextOpt(context);
+ if (r < -1) {
+ fprintf(stderr, "%s: %s\n",
+ poptBadOption(context, POPT_BADOPTION_NOALIAS),
+ poptStrerror(r));
+
+ return -1;
+ }
+ fooptr = poptGetArg(context);
+ if (fooptr != NULL) {
+ strncpy(list, fooptr, sizeof(list) - 1);
+ list[99] = '\0';
+ for (x=0;list[x];x++) list[x]=toupper(list[x]);
+ }
+ if (waitseconds) {
+ alarmlen = waitseconds;
+ }
+ foo[0]=foo[1]='\0';
+
+ signal(SIGTERM,reset_term);
+ alarm(alarmlen);
+ signal(SIGALRM,reset_term);
+
+ tcgetattr(0,&tp);
+ tp_if=tp.c_iflag;
+ tp_of=tp.c_oflag;
+ tp_lf=tp.c_lflag;
+ tp.c_iflag=0;
+ tp.c_oflag &= ~OPOST;
+ tp.c_lflag &= ~(ISIG | ICANON);
+ tcsetattr(0,TCSANOW,&tp);
+ tp.c_iflag=tp_if;
+ tp.c_oflag=tp_of;
+ tp.c_lflag=tp_lf;
+
+ ufds.events = POLLIN;
+ ufds.fd = 0;
+
+ if (waitseconds && waitmessage) {
+ waitprint = alloca (strlen(waitmessage)+15); /* long enough */
+ waitprint[0] = '\r';
+ waitsprint = waitprint + 1;
+ }
+
+ while (1) {
+ if (waitseconds && waitmessage) {
+ sprintf (waitsprint, waitmessage, waitseconds);
+ write (1, waitprint, strlen(waitprint));
+ }
+ r = poll(&ufds, 1, alarmlen ? 1000 : -1);
+ if (r == 0) {
+ /* we have waited a whole second with no keystroke... */
+ waitseconds--;
+ }
+ if (r > 0) {
+ read(0,foo,1);
+ foo[0]=toupper(foo[0]);
+ /* Die if we get a control-c or control-d */
+ if (ignore_control == 0) {
+ if (foo[0]==3 || foo[0]==4) reset_term(1);
+ }
+ /* Don't let a null character be interpreted as a match
+ by strstr */
+ if (foo[0] != 0) {
+ if (strcmp(list, "") == 0 || strstr(list,foo)) {
+ reset_term(0);
+ }
+ }
+ }
+ }
+}
|