Style(9) cleanup.
[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.3 2004/03/24 17:46:23 cpressey Exp $
29 */
30
31 #include <sys/types.h>
32 #include <sys/stat.h>
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <ctype.h>
38
39 static void dokey(char *, char *);
40 static void clearkeys(void);
41 static void lockkeys(void);
42 static void usage(void);
43 static void getinit(void);
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 int
77 main(int argc, char **argv)
78 {
79         /* these are defined in the getopt routine                       */
80         extern char *optarg;    /* argument give to an option            */
81         extern int  optind;     /* argv index after option processing    */
82
83         int option;             /* option character returned by getopt   */
84         int initf = 0;          /* read initialization file              */
85         int lockf = 0;          /* lock keys after loading strings       */
86         int clearf = 0;         /* clear all keys before loading strings */
87
88         strlcpy(prog, *argv, sizeof(prog));  /* store program name       */
89
90         if(argc == 1) usage();  /* program requires options              */
91
92         /* get options */
93         while ((option = getopt(argc, argv, "cli")) != -1)
94         switch(option)
95         {
96                 case 'c' :
97                         clearf++;
98                         break;
99                 case 'l' :
100                         lockf++;
101                         break;
102                 case 'i' :
103                         initf++;
104                         break;
105                 case '?' :
106                         usage();
107           }
108
109         if (VT200_7BIT)
110                 printf("\033[62;1\"p");    /* vt200 7 bits */
111         else
112                 printf("\033[62;2\"p");    /* vt200 8 bits */
113
114         if(clearf) clearkeys();
115
116         if (initf) getinit();
117
118         /* process {key, key string} pairs.  Note optind is index to argv
119            for first pair.  By adding 1 to optind insures that a pair exists
120            i.e. the last key has a key string.                             */
121
122         while(optind + 1 < argc)
123         {
124                 dokey(argv[optind], argv[optind+1]);
125                 optind += 2;
126         }
127
128         if(lockf) lockkeys();
129
130         exit(0);
131 }
132
133 /****************************************************************************/
134
135 /*
136  *      Load the VT220 SHIFT-FNKEY value, the basic pattern is
137  *              "\EP1;1|"+KEYNAME+"/"+VAL_AS_HEX+"\E\\"
138  *      that is, literally what is in quotes (w/o quotes) then the
139  *      name of the key from the keytable above (a numeric string)
140  *      then a slash, then the string value as hex pairs then ESC-BACKSLASH
141  *
142  *      Note: you can gang together key defns with semicolons but that
143  *      would complicate things, especially error handling, so do it all
144  *      for each pair, who cares, really.
145  */
146
147 void
148 dokey(char *nm, char *val)
149 {
150         char *scr;
151         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 void
170 clearkeys(void)
171 {
172         printf("%cP0;1|%c\\",ESC,ESC);
173         fflush(stdout);
174 }
175
176 /****************************************************************************/
177
178 void
179 lockkeys(void)
180 {
181         printf("%cP1;0|%c\\",ESC,ESC);
182         fflush(stdout);
183 }
184
185 /****************************************************************************/
186
187 void
188 usage(void)
189 {
190         int i;
191
192         fprintf(stderr,"Usage: %s [-cil] [keyname string keyname string...]\n\n",prog);
193         fprintf(stderr,"The following options are available\n");
194         fprintf(stderr,"\t-c\tclears keys first\n");
195         fprintf(stderr,"\t-l\t[sets then] locks further setting\n");
196         fprintf(stderr,"\t-i\tfirst read initialization file $HOME/%s\n",INITFILE);
197         fprintf(stderr,"(note that the only way to unlock is via Set-Up)\n\n");
198         fprintf(stderr,"Keyname is one of:\n\t");
199         for(i=0; keys[i].name != NULL; i++)
200                 fprintf(stderr,"%s ",keys[i].name);
201         fprintf(stderr,"\nKeyname is SHIFTED function key that sends the string\n\n");
202         fprintf(stderr,"Strings may need quoting to protect from shell\n");
203         fprintf(stderr,"You must specify an option or key,string pairs\n\n");
204         exit(1);
205 }
206
207 /****************************************************************************/
208
209 /* This routine process the INITFILE.  This file expects lines in the format
210
211                 <ws> keyname ws string
212
213    Where ws is white space (spaces or tabs) and <ws> is optional white space.
214    The string may include spaces or tabs and need not be quoted.  If the
215    string has the sequence of "\n" then a newline character is included in
216    the string.
217
218    examples:
219
220         F6      ls -lg\n
221         F7      uulog -s
222
223 */
224
225 void
226 getinit(void)
227 {
228         char *home;             /* user's home directory                */
229         char path[BUFSIZ];      /* full path name of init file          */
230         char buf[BUFSIZ];       /* buffer to hold 1 line from init file */
231         char key[BUFSIZ];       /* buffer, to hold specified fcn key    */
232         char keystr[BUFSIZ];    /* string associated with fcn key       */
233         char *ptr;              /* pointer to transverse buf            */
234         int i, j;               /* array indices                        */
235         int statflag;           /* whether init file is regular & readable */
236         struct stat statbuf;    /* stat of the init file                */
237         FILE *fp;               /* file pointer to init file            */
238
239         /* construct full path name for init file */
240         home = getenv("HOME");
241         snprintf(path, sizeof(path), "%s/%s", home, INITFILE);
242
243         /* check status if init file    */
244         if (stat(path, &statbuf) != -1)
245         {
246             statflag = statbuf.st_mode & S_IFREG && statbuf.st_mode & S_IREAD;
247             if (!statflag || (fp = fopen(path, "r")) == NULL)
248             {
249                 fprintf(stderr, "couldn't open initalization file: %s\n", path);
250                 exit(1);
251             }
252
253             /* process lines from init file */
254             while (fgets(buf, BUFSIZ, fp) != NULL)
255             {
256                 /* variable initializations */
257                 i = 0; j = 0;
258                 key[0] = '\0'; keystr[0] = '\0';
259                 ptr = buf;
260
261                 while (*ptr == ' ' || *ptr == '\t') ptr++; /*skip whitespace*/
262
263                 if (*ptr == '\n') break;   /* we hit an emtpy line          */
264
265                 while (!isspace(*ptr) && *ptr != '\0')     /* get keyname   */
266                     key[i++] = *ptr++;
267                 key[i] = '\0'; /* place EOS in buffer */
268
269                 while (*ptr == ' ' || *ptr == '\t') ptr++; /*skip whitespace*/
270
271                 while (*ptr != '\n' && *ptr != '\0')       /* get string    */
272                 {
273                     /* check if string is to include newline i.e. \n        */
274                     if (*ptr == '\\' && *(ptr+1) == 'n')
275                     {
276                           keystr[j] = '\012';
277                           ptr++;
278                     }
279                     else
280                           keystr[j] = *ptr;
281                     j++; ptr++;
282                 }
283                 keystr[j] = '\0';     /* place EOS in buffer  */
284                 dokey(key, keystr);   /* load key with string */
285             }
286         }
287         else
288         {
289             fprintf(stderr, "init file %s not found\n\n", path);
290             usage();
291         }
292 }