/* * Trivial program to load VT220 Function keys with strings, * note that the values only get sent when the key is shifted * (shoulda been an option to flip the shift set like the Z19!) * * Typing no args gives help, basically pairs of keyname/value * strings. * * Author, Author: Barry Shein, Boston University * * HISTORY {1} 30-Oct-85 Kenneth J. Lester (ken) at ektools Added the necessary code to read an initialization file. This should make it easier to used this program. Also added code that will set-up the terminal in vt200 (this saves the user the trouble of checking if the set-up is in vt200). Restructed the main function to use getopt, for argument processing. Alterated usage function to include new "i" option (init file) -hm minor modifications for pcvt 2.0 release $FreeBSD: src/usr.sbin/pcvt/userkeys/vt220keys.c,v 1.8 2002/04/22 13:44:45 des Exp $ */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <unistd.h> /* * The default toupper() macro is stupid, will toupper anything */ #ifdef toupper #undef toupper #endif #define toupper(c) (islower(c) ? ((c)-' ') : c) #define VT200_7BIT 1 #define ESC 033 #define INITFILE ".vt220rc" struct keynames { char *name ; char *string ; } keys[] = { "F6", "17", "F7", "18", "F8", "19", "F9", "20", "F10", "21", "F11", "23", "ESC", "23", "F12", "24", "BS", "24", "F13", "25", "LF", "25", "F14", "26", "HELP", "28", "DO", "29", "F17", "31", "F18", "32", "F19", "33", "F20", "34", NULL, NULL }; char prog[BUFSIZ]; main(argc,argv) int argc; char *argv[]; { int option; /* option character returned by getopt */ int initf = 0; /* read initialization file */ int lockf = 0; /* lock keys after loading strings */ int clearf = 0; /* clear all keys before loading strings */ strlcpy(prog, *argv, sizeof(prog)); /* store program name */ if(argc == 1) usage(); /* program requires options */ /* get options */ while ((option = getopt(argc, argv, "cli")) != -1) switch(option) { case 'c' : clearf++; break; case 'l' : lockf++; break; case 'i' : initf++; break; case '?' : usage(); } if (VT200_7BIT) printf("\033[62;1\"p"); /* vt200 7 bits */ else printf("\033[62;2\"p"); /* vt200 8 bits */ if(clearf) clearkeys(); if (initf) getinit(); /* process {key, key string} pairs. Note optind is index to argv for first pair. By adding 1 to optind insures that a pair exists i.e. the last key has a key string. */ while(optind + 1 < argc) { dokey(argv[optind], argv[optind+1]); optind += 2; } if(lockf) lockkeys(); exit(0); } /****************************************************************************/ /* * Load the VT220 SHIFT-FNKEY value, the basic pattern is * "\EP1;1|"+KEYNAME+"/"+VAL_AS_HEX+"\E\\" * that is, literally what is in quotes (w/o quotes) then the * name of the key from the keytable above (a numeric string) * then a slash, then the string value as hex pairs then ESC-BACKSLASH * * Note: you can gang together key defns with semicolons but that * would complicate things, especially error handling, so do it all * for each pair, who cares, really. */ dokey(nm,val) char *nm, *val; { register char *scr; register struct keynames *kp; for(scr = nm; *scr = toupper(*scr); scr++) ; for(kp = keys; kp->name != NULL; kp++) if(strcmp(nm,kp->name) == 0) { printf("%cP1;1|%s/",ESC,kp->string); while(*val) printf("%02x",*val++); printf("%c\\",ESC); fflush(stdout); return; } fprintf(stderr,"Bad key name: %s\n",nm); usage(); /* bad key name, give up */ } /****************************************************************************/ clearkeys() { printf("%cP0;1|%c\\",ESC,ESC); fflush(stdout); } /****************************************************************************/ lockkeys() { printf("%cP1;0|%c\\",ESC,ESC); fflush(stdout); } /****************************************************************************/ usage() { int i; fprintf(stderr,"usage: %s [-cil] [keyname string keyname string...]\n\n",prog); fprintf(stderr,"The following options are available\n"); fprintf(stderr,"\t-c\tclears keys first\n"); fprintf(stderr,"\t-l\t[sets then] locks further setting\n"); fprintf(stderr,"\t-i\tfirst read initialization file $HOME/%s\n",INITFILE); fprintf(stderr,"(note that the only way to unlock is via Set-Up)\n\n"); fprintf(stderr,"Keyname is one of:\n\t"); for(i=0; keys[i].name != NULL; i++) fprintf(stderr,"%s ",keys[i].name); fprintf(stderr,"\nKeyname is SHIFTED function key that sends the string\n\n"); fprintf(stderr,"Strings may need quoting to protect from shell\n"); fprintf(stderr,"You must specify an option or key,string pairs\n\n"); exit(1); } /****************************************************************************/ /* This routine process the INITFILE. This file expects lines in the format <ws> keyname ws string Where ws is white space (spaces or tabs) and <ws> is optional white space. The string may include spaces or tabs and need not be quoted. If the string has the sequence of "\n" then a newline character is included in the string. examples: F6 ls -lg\n F7 uulog -s */ #include <sys/types.h> #include <sys/stat.h> getinit() { char *home; /* user's home directory */ char path[BUFSIZ]; /* full path name of init file */ char buf[BUFSIZ]; /* buffer to hold 1 line from init file */ char key[BUFSIZ]; /* buffer, to hold specified fcn key */ char keystr[BUFSIZ]; /* string associated with fcn key */ char *ptr; /* pointer to transverse buf */ int i, j; /* array indices */ int statflag; /* whether init file is regular & readable */ struct stat statbuf; /* stat of the init file */ FILE *fp; /* file pointer to init file */ /* construct full path name for init file */ home = getenv("HOME"); snprintf(path, sizeof(path), "%s/%s", home, INITFILE); /* check status if init file */ if (stat(path, &statbuf) != -1) { statflag = statbuf.st_mode & S_IFREG && statbuf.st_mode & S_IREAD; if (!statflag || (fp = fopen(path, "r")) == NULL) { fprintf(stderr, "couldn't open initalization file: %s\n", path); exit(1); } /* process lines from init file */ while (fgets(buf, BUFSIZ, fp) != NULL) { /* variable initializations */ i = 0; j = 0; key[0] = '\0'; keystr[0] = '\0'; ptr = buf; while (*ptr == ' ' || *ptr == '\t') ptr++; /*skip whitespace*/ if (*ptr == '\n') break; /* we hit an emtpy line */ while (!isspace(*ptr) && *ptr != '\0') /* get keyname */ key[i++] = *ptr++; key[i] = '\0'; /* place EOS in buffer */ while (*ptr == ' ' || *ptr == '\t') ptr++; /*skip whitespace*/ while (*ptr != '\n' && *ptr != '\0') /* get string */ { /* check if string is to include newline i.e. \n */ if (*ptr == '\\' && *(ptr+1) == 'n') { keystr[j] = '\012'; ptr++; } else keystr[j] = *ptr; j++; ptr++; } keystr[j] = '\0'; /* place EOS in buffer */ dokey(key, keystr); /* load key with string */ } } else { fprintf(stderr, "init file %s not found\n\n", path); usage(); } }