Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / usr.sbin / pcvt / userkeys / vt220keys.c
1 /*
2  *      Trivial program to load VT220 Function keys with strings,
3  *      note that the values only get sent when the key is shifted
4  *      (shoulda been an option to flip the shift set like the Z19!)
5  *
6  *      Typing no args gives help, basically pairs of keyname/value
7  *      strings.
8  *
9  *      Author, Author: Barry Shein, Boston University
10  *
11  * HISTORY
12   {1}   30-Oct-85  Kenneth J. Lester (ken) at ektools
13
14         Added the necessary code to read an initialization file.  This
15         should make it easier to used this program.  Also added code
16         that will set-up the terminal in vt200 (this saves the user the
17         trouble of checking if the set-up is in vt200).
18
19         Restructed  the  main  function  to  use   getopt,  for  argument
20         processing.
21
22         Alterated usage function  to include  new "i"  option (init file)
23
24
25         -hm     minor modifications for pcvt 2.0 release
26
27 $FreeBSD: src/usr.sbin/pcvt/userkeys/vt220keys.c,v 1.5.6.1 2001/05/12 10:11:42 kris Exp $
28 $DragonFly: src/usr.sbin/pcvt/userkeys/Attic/vt220keys.c,v 1.2 2003/06/17 04:29:59 dillon Exp $
29 */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <ctype.h>
35
36 /*
37  *      The default toupper() macro is stupid, will toupper anything
38  */
39
40 #ifdef toupper
41 #undef toupper
42 #endif
43 #define toupper(c) (islower(c) ? ((c)-' ') : c)
44
45 #define VT200_7BIT 1
46 #define ESC 033
47 #define INITFILE ".vt220rc"
48
49 struct keynames {
50   char *name ;
51   char *string ;
52 } keys[] = {
53   "F6", "17",
54   "F7", "18",
55   "F8", "19",
56   "F9", "20",
57   "F10", "21",
58   "F11", "23",
59   "ESC", "23",
60   "F12", "24",
61   "BS", "24",
62   "F13", "25",
63   "LF", "25",
64   "F14", "26",
65   "HELP", "28",
66   "DO", "29",
67   "F17", "31",
68   "F18", "32",
69   "F19", "33",
70   "F20", "34",
71     NULL, NULL
72 };
73
74 char prog[BUFSIZ];
75
76 main(argc,argv)
77         int argc;
78         char *argv[];
79 {
80         /* these are defined in the getopt routine                       */
81         extern char *optarg;    /* argument give to an option            */
82         extern int  optind;     /* argv index after option processing    */
83
84         int option;             /* option character returned by getopt   */
85         int initf = 0;          /* read initialization file              */
86         int lockf = 0;          /* lock keys after loading strings       */
87         int clearf = 0;         /* clear all keys before loading strings */
88
89         strlcpy(prog, *argv, sizeof(prog));  /* store program name       */
90
91         if(argc == 1) usage();  /* program requires options              */
92
93         /* get options */
94         while ((option = getopt(argc, argv, "cli")) != -1)
95         switch(option)
96         {
97                 case 'c' :
98                         clearf++;
99                         break;
100                 case 'l' :
101                         lockf++;
102                         break;
103                 case 'i' :
104                         initf++;
105                         break;
106                 case '?' :
107                         usage();
108           }
109
110         if (VT200_7BIT)
111                 printf("\033[62;1\"p");    /* vt200 7 bits */
112         else
113                 printf("\033[62;2\"p");    /* vt200 8 bits */
114
115         if(clearf) clearkeys();
116
117         if (initf) getinit();
118
119         /* process {key, key string} pairs.  Note optind is index to argv
120            for first pair.  By adding 1 to optind insures that a pair exists
121            i.e. the last key has a key string.                             */
122
123         while(optind + 1 < argc)
124         {
125                 dokey(argv[optind], argv[optind+1]);
126                 optind += 2;
127         }
128
129         if(lockf) lockkeys();
130
131         exit(0);
132 }
133
134 /****************************************************************************/
135
136 /*
137  *      Load the VT220 SHIFT-FNKEY value, the basic pattern is
138  *              "\EP1;1|"+KEYNAME+"/"+VAL_AS_HEX+"\E\\"
139  *      that is, literally what is in quotes (w/o quotes) then the
140  *      name of the key from the keytable above (a numeric string)
141  *      then a slash, then the string value as hex pairs then ESC-BACKSLASH
142  *
143  *      Note: you can gang together key defns with semicolons but that
144  *      would complicate things, especially error handling, so do it all
145  *      for each pair, who cares, really.
146  */
147
148 dokey(nm,val) char *nm, *val;
149 {
150         register char *scr;
151         register struct keynames *kp;
152
153         for(scr = nm; *scr = toupper(*scr); scr++)
154                         ;
155         for(kp = keys; kp->name != NULL; kp++)
156           if(strcmp(nm,kp->name) == 0) {
157             printf("%cP1;1|%s/",ESC,kp->string);
158             while(*val) printf("%02x",*val++);
159             printf("%c\\",ESC);
160             fflush(stdout);
161             return;
162         }
163         fprintf(stderr,"Bad key name: %s\n",nm);
164         usage();        /* bad key name, give up */
165 }
166
167 /****************************************************************************/
168
169 clearkeys()
170 {
171         printf("%cP0;1|%c\\",ESC,ESC);
172         fflush(stdout);
173 }
174
175 /****************************************************************************/
176
177 lockkeys()
178 {
179         printf("%cP1;0|%c\\",ESC,ESC);
180         fflush(stdout);
181 }
182
183 /****************************************************************************/
184
185 usage()
186 {
187         int i;
188
189         fprintf(stderr,"Usage: %s [-cil] [keyname string keyname string...]\n\n",prog);
190         fprintf(stderr,"The following options are available\n");
191         fprintf(stderr,"\t-c\tclears keys first\n");
192         fprintf(stderr,"\t-l\t[sets then] locks further setting\n");
193         fprintf(stderr,"\t-i\tfirst read initialization file $HOME/%s\n",INITFILE);
194         fprintf(stderr,"(note that the only way to unlock is via Set-Up)\n\n");
195         fprintf(stderr,"Keyname is one of:\n\t");
196         for(i=0; keys[i].name != NULL; i++)
197                 fprintf(stderr,"%s ",keys[i].name);
198         fprintf(stderr,"\nKeyname is SHIFTED function key that sends the string\n\n");
199         fprintf(stderr,"Strings may need quoting to protect from shell\n");
200         fprintf(stderr,"You must specify an option or key,string pairs\n\n");
201         exit(1);
202 }
203
204 /****************************************************************************/
205
206 /* This routine process the INITFILE.  This file expects lines in the format
207
208                 <ws> keyname ws string
209
210    Where ws is white space (spaces or tabs) and <ws> is optional white space.
211    The string may include spaces or tabs and need not be quoted.  If the
212    string has the sequence of "\n" then a newline character is included in
213    the string.
214
215    examples:
216
217         F6      ls -lg\n
218         F7      uulog -s
219
220 */
221
222 #include <sys/types.h>
223 #include <sys/stat.h>
224
225 getinit()
226 {
227         char *home;             /* user's home directory                */
228         char path[BUFSIZ];      /* full path name of init file          */
229         char buf[BUFSIZ];       /* buffer to hold 1 line from init file */
230         char key[BUFSIZ];       /* buffer, to hold specified fcn key    */
231         char keystr[BUFSIZ];    /* string associated with fcn key       */
232         char *ptr;              /* pointer to transverse buf            */
233         int i, j;               /* array indices                        */
234         int statflag;           /* whether init file is regular & readable */
235         struct stat statbuf;    /* stat of the init file                */
236         FILE *fp;               /* file pointer to init file            */
237
238         /* construct full path name for init file */
239         home = getenv("HOME");
240         snprintf(path, sizeof(path), "%s/%s", home, INITFILE);
241
242         /* check status if init file    */
243         if (stat(path, &statbuf) != -1)
244         {
245             statflag = statbuf.st_mode & S_IFREG && statbuf.st_mode & S_IREAD;
246             if (!statflag || (fp = fopen(path, "r")) == NULL)
247             {
248                 fprintf(stderr, "couldn't open initalization file: %s\n", path);
249                 exit(1);
250             }
251
252             /* process lines from init file */
253             while (fgets(buf, BUFSIZ, fp) != NULL)
254             {
255                 /* variable initializations */
256                 i = 0; j = 0;
257                 key[0] = '\0'; keystr[0] = '\0';
258                 ptr = buf;
259
260                 while (*ptr == ' ' || *ptr == '\t') ptr++; /*skip whitespace*/
261
262                 if (*ptr == '\n') break;   /* we hit an emtpy line          */
263
264                 while (!isspace(*ptr) && *ptr != '\0')     /* get keyname   */
265                     key[i++] = *ptr++;
266                 key[i] = '\0'; /* place EOS in buffer */
267
268                 while (*ptr == ' ' || *ptr == '\t') ptr++; /*skip whitespace*/
269
270                 while (*ptr != '\n' && *ptr != '\0')       /* get string    */
271                 {
272                     /* check if string is to include newline i.e. \n        */
273                     if (*ptr == '\\' && *(ptr+1) == 'n')
274                     {
275                           keystr[j] = '\012';
276                           ptr++;
277                     }
278                     else
279                           keystr[j] = *ptr;
280                     j++; ptr++;
281                 }
282                 keystr[j] = '\0';     /* place EOS in buffer  */
283                 dokey(key, keystr);   /* load key with string */
284             }
285         }
286         else
287         {
288             fprintf(stderr, "init file %s not found\n\n", path);
289             usage();
290         }
291 }