FreeBSD-5.3/usr.sbin/pcvt/userkeys/vt220keys.c

Compare this file to the similar file:
Show the results in this format:

/*
 *      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();
        }
}