Annotation of GNUtools/emacs/src/hftctl.c, revision 1.1.1.1

1.1       root        1: /* IBM has disclaimed copyright on this module.  */
                      2: 
                      3: /***************************************************************/
                      4: /*                                                             */
                      5: /* Function: hftctl                                            */
                      6: /*                                                             */
                      7: /* Syntax:                                                     */
                      8: /*    #include <sys/ioctl.h>                                   */
                      9: /*    #include <sys/hft.h>                                     */
                     10: /*                                                             */
                     11: /*    int hftctl(fildes, request, arg )                        */
                     12: /*    int fildes, request;                                     */
                     13: /*    char *arg;                                               */
                     14: /*                                                             */
                     15: /* Description:                                                */
                     16: /*                                                             */
                     17: /*    Does the following:                                      */
                     18: /*      1. determines if fildes is pty                         */
                     19: /*         does normal ioctl it is not                         */
                     20: /*      2. places fildes into raw mode                         */
                     21: /*      3. converts ioctl arguments to datastream              */
                     22: /*      4. waits for 2 secs for acknowledgement before         */
                     23: /*         timimg out.                                         */
                     24: /*      5. places response in callers buffer ( just like       */
                     25: /*         ioctl.                                              */
                     26: /*      6. returns fildes to its original mode                 */
                     27: /*                                                             */
                     28: /*    User of this program should review steps 1,4, and 3.     */
                     29: /*    hftctl makes no check on the request type. It must be    */
                     30: /*    a HFT ioctl that is supported remotely.                  */
                     31: /*    This program will use the SIGALRM and alarm(2).  Any     */
                     32: /*    Previous alarms are lost.                                */
                     33: /*                                                             */
                     34: /*    Users of this program are free to modify it any way      */
                     35: /*    they want.                                               */
                     36: /*                                                             */
                     37: /* Return Value:                                               */
                     38: /*                                                             */
                     39: /*    If ioctl fails, a value of -1 is returned and errno      */
                     40: /*    is set to indicate the error.                            */
                     41: /*                                                             */
                     42: /***************************************************************/
                     43: 
                     44: 
                     45: #include <stdio.h>
                     46: #include <fcntl.h>
                     47: #include <errno.h>
                     48: #include <setjmp.h>
                     49: #include <sys/ioctl.h>
                     50: #include <sys/signal.h>
                     51: #include <sys/devinfo.h>
                     52: #include <termios.h>
                     53: #include <termio.h>
                     54: #include <sys/hft.h>
                     55: #include <sys/uio.h>
                     56: #include <sys/tty.h>
                     57: /* #include <sys/pty.h> */
                     58: #define REMOTE 0x01
                     59: 
                     60: #undef ioctl
                     61: static char     SCCSid[] = "com/gnuemacs/src,3.1,9021-90/05/03-5/3/90";
                     62: 
                     63: /*************** LOCAL DEFINES **********************************/
                     64: 
                     65: typedef int    (*FUNC)();     /* pointer to a function        */
                     66: 
                     67: #define QDEV   ((HFQPDEVCH<<8)|HFQPDEVCL)
                     68: #define QLOC   ((HFQLOCCH<<8)|HFQLOCCL)
                     69: #define QPS    ((HFQPRESCH<<8)|HFQPRESCL)
                     70: 
                     71: #ifndef TCGETS 
                     72: #define TCGETS TCGETA
                     73: #endif
                     74: #ifndef TCSETS
                     75: #define TCSETS TCSETA
                     76: #endif
                     77: 
                     78: /*************** EXTERNAL / GLOBAL DATA AREA ********************/
                     79: 
                     80: static int              hfqry();
                     81: static int              hfskbd();
                     82:        char            *malloc();
                     83: 
                     84: extern int              errno;
                     85: static jmp_buf          hftenv;
                     86: static int              is_ack_vtd;
                     87: static FUNC             sav_alrm;
                     88: static struct hfctlreq  req =
                     89:                        { 0x1b,'[','x',0,0,0,21,HFCTLREQCH,HFCTLREQCL};
                     90: static struct hfctlack  ACK =
                     91:                        { 0x1b,'[','x',0,0,0,21,HFCTLACKCH,HFCTLACKCL};
                     92: 
                     93:        /* FUNC             signal(); */
                     94: 
                     95: /*************** LOCAL MACROS ***********************************/
                     96: 
                     97: #define HFTYPE(p)   ((p->hf_typehi<<8)|(p->hf_typelo))
                     98: 
                     99: #define BYTE4(p)    ((p)[0]<<24 | (p)[1]<<16 | (p)[2]<<8 | (p)[3])
                    100: 
                    101:                                        /* read a buffer        */
                    102: #define RD_BUF(f,p,l) \
                    103:         while ((l)) \
                    104:           if ((j = read((f),(p),(l))) < 0) \
                    105:              if (errno != EINTR) return (-1); \
                    106:              else continue; \
                    107:           else { (l) -= j; (p) += j; }
                    108: 
                    109: /*************** function prototypes ***************************/
                    110: #ifdef __STDC__
                    111: static GT_ACK (int fd, int req, char *buf);
                    112: static WR_REQ (int fd, int request, int cmdlen, char *cmd, int resplen);
                    113: static hft_alrm(int sig);
                    114: #else
                    115: static GT_ACK ();
                    116: static WR_REQ ();
                    117: static hft_alrm ();
                    118: #endif
                    119: 
                    120: /*************** HFTCTL FUNCTION *******************************/
                    121: 
                    122: hftctl (fd, request, arg)
                    123:      int     fd;
                    124:      int     request;
                    125:      union {
                    126:        struct hfintro *intro;
                    127:        struct hfquery *query;
                    128:        char           *c;
                    129:      } arg;
                    130: {
                    131: 
                    132:   int             i;
                    133:   int             fd_flag;     /* fcntl flags          */
                    134:   register union {
                    135:     struct hfintro         *cmd; /* p.cmd - intro des.   */
                    136:     struct hfqphdevc       *ph;        /* p.ph  - physical dev.*/
                    137:     char            *c;                /* p.c   - char ptr     */
                    138:   }               p;           /* general pointer      */
                    139:   int             pty_new;     /* pty modes            */
                    140:   int             pty_old;
                    141:   int             retcode;
                    142:   struct termios   term_new;   /* terminal attributes  */
                    143:   struct termios   term_old;
                    144:   struct devinfo       devInfo; /* defined in sys/devinfo.h */
                    145: 
                    146: 
                    147:   if (ioctl (fd, IOCINFO, &devInfo) == -1) return(-1);
                    148: 
                    149:   if (devInfo.devtype != DD_PSEU) /* is it a pty? */
                    150:     return (ioctl(fd, request, arg)); /* no, do IOCTL */
                    151: 
                    152:   /******* START PTY **************/
                    153:   /**  Pty found, possible HFT    */
                    154:   /** set new file des as raw     */
                    155:   /** as you can.                 */
                    156:   /********************************/
                    157: 
                    158:   /* Get current state of file    */
                    159:   /* descriptor & save            */
                    160:   if ((fd_flag = fcntl (fd, F_GETFL, 0)) == -1) return (-1);
                    161:   if (ioctl (fd, TCGETS, &term_old) == -1) return (-1);
                    162:   /* set terminal attr to raw     */
                    163:   /* and to delay on read         */
                    164:   pty_new = pty_old | REMOTE;
                    165:   memcpy (&term_new, &term_old, sizeof (term_new));
                    166:   term_new.c_iflag = 0;
                    167:   term_new.c_oflag = 0;
                    168:   term_new.c_lflag = 0;
                    169:   /* term_new.c_line  = 0; */
                    170:   for (i = 1; i <= 5; i++)
                    171:     term_new.c_cc[i] = 0;
                    172:   term_new.c_cc[0] = -1;
                    173:   ioctl (fd, TCSETS, &term_new);
                    174:   if (fcntl (fd, F_SETFL, fd_flag & ~O_NDELAY) == -1)
                    175:     return(-1);
                    176:   /* call spacific function       */
                    177:   if (request == HFSKBD)
                    178:     retcode = hfskbd (fd, request, arg.c);
                    179:   else                         /* assume HFQUERY */
                    180:     retcode = hfqry (fd, request, arg.c);
                    181: 
                    182:   fcntl (fd, F_SETFL, fd_flag); /* reset terminal to original   */
                    183:   ioctl (fd, TCSETS, &term_old);
                    184: 
                    185: 
                    186:   return (retcode);             /* return error                 */
                    187: }
                    188: 
                    189: /*************** HFSKBD  FUNCTION ******************************/
                    190: static int
                    191: hfskbd (fd, request, arg)
                    192:         int     fd;
                    193:         int     request;
                    194:         struct hfbuf *arg;
                    195: {
                    196:   WR_REQ(fd, request, arg->hf_buflen, arg->hf_bufp,0);
                    197:   return (GT_ACK(fd, request, arg->hf_bufp));
                    198: }
                    199: 
                    200: /*************** HFQUERY FUNCTION ******************************/
                    201: static int
                    202: hfqry (fd, request, arg)
                    203:         int     fd;
                    204:         int     request;
                    205:         struct hfquery *arg;
                    206: {
                    207:   WR_REQ(fd, request, arg->hf_cmdlen, arg->hf_cmd, arg->hf_resplen);
                    208:   return (GT_ACK(fd, request, arg->hf_resp));
                    209: }
                    210: 
                    211: 
                    212: /*************** GT_ACK FUNCTION ******************************/
                    213: static int
                    214: GT_ACK (fd, req, buf)
                    215:         int     fd;
                    216:         int     req;
                    217:         char   *buf;
                    218: {
                    219:   struct hfctlack ack;
                    220:   int             i = sizeof (ack);
                    221:   int             j = 0;
                    222:   union {
                    223:     char            *c;
                    224:     struct hfctlack *ack;
                    225:   }               p;
                    226: 
                    227:   is_ack_vtd = 0;              /* flag no ACT VTD yet         */
                    228: 
                    229:   if (setjmp (hftenv))         /* set environment in case     */
                    230:     {                          /* of time out                 */
                    231:       errno = ENODEV;          /* if time out, set errno      */
                    232:       return (-1);             /* flag error                  */
                    233:     }
                    234: 
                    235:   alarm(3);                    /* time out in 3 secs          */
                    236:   sav_alrm = (FUNC) signal (SIGALRM, (void(*)())hft_alrm); /* prepare to catch time out */
                    237: 
                    238:   p.ack = &ack;
                    239:   while (! is_ack_vtd)         /* do until valid ACK VTD      */
                    240:     {
                    241:       RD_BUF(fd, p.c, i);      /* read until a ACK VTD is fill*/
                    242: 
                    243:       if (! memcmp (&ack, &ACK, sizeof (HFINTROSZ)) /* the ACK intro &  */
                    244:          && (ack.hf_request == req)) /* is it the response we want ?*/
                    245:        {                       /* yes, ACK VTD found          */
                    246:          is_ack_vtd = 1;       /* quickly, flag it            */
                    247:          break;                /* get the %$%#@ out of here   */
                    248:        }
                    249: 
                    250:       p.ack = &ack;            /* no, then skip 1st           */
                    251:       ++p.c;                   /* char and start over         */
                    252:       i = sizeof (ack) - 1;    /* one less ESC to cry over    */
                    253: 
                    254:       while ((*p.c != 0x1b) && i) /* scan for next ESC           */
                    255:        { ++p.c; --i; }         /* if any                      */
                    256: 
                    257:       (i ? memcpy (&ack, p.c, i) : 0); /* if any left over, then move */
                    258:       p.ack = &ack;            /* ESC to front of ack struct  */
                    259:       p.c += i;                        /* skip over whats been read   */
                    260:       i = sizeof (ack) - i;    /* set whats left to be read   */
                    261:     }                          /***** TRY AGAIN               */
                    262: 
                    263:   alarm(0);                    /* ACK VTD received, reset alrm*/
                    264:   signal (SIGALRM, (void(*)())sav_alrm); /* reset signal                */
                    265: 
                    266:   if (i = ack.hf_arg_len)      /* any data following ?        */
                    267:     {                          /* yes,                        */
                    268:       RD_BUF(fd,buf,i);                /* read until it is received   */
                    269:     }
                    270: 
                    271:   if (errno = ack.hf_retcode)  /* set errno based on returned */
                    272:     return (-1);               /* code, if 0, then no error   */
                    273:   else
                    274:     return (0);                        /* if set, then error returned */
                    275: }
                    276: 
                    277: /*************** HFT_ALRM FUNCTION ******************************/
                    278: static int
                    279: hft_alrm (sig)                    /* Function hft_alrm - handle  */
                    280:         int sig;               /* alarm signal               */
                    281: {
                    282:   signal (SIGALRM, (void(*)())sav_alrm); /* reset to previous          */
                    283: 
                    284:   if (is_ack_vtd)              /* has ack vtd arrived ?      */
                    285:     return(0);                 /* yes, then continue         */
                    286:   else                         /* no, then return with error */
                    287:     longjmp (hftenv, -1);
                    288: 
                    289: }
                    290: 
                    291: /*********************************************************************/
                    292: /***                                                               ***/
                    293: /***  NOTE: Both the HFCTLREQ and the arg structure should be      ***/
                    294: /***        sent in one io write operation.  If terminal           ***/
                    295: /***        emulators are in NODELAY mode then multiple writes     ***/
                    296: /***        may cause bogus information to be read by the emulator ***/
                    297: /***        depending on the timing.                               ***/
                    298: /***                                                               ***/
                    299: /*********************************************************************/
                    300: 
                    301: static int
                    302: WR_REQ (fd, request, cmdlen, cmd, resplen)
                    303:        int             fd;
                    304:        int             request;
                    305:        int             cmdlen;
                    306:        char           *cmd;
                    307:        int             resplen;
                    308: {
                    309:   struct {
                    310:     char            *c;
                    311:     struct hfctlreq *req;
                    312:   }              p;
                    313:   int            size;
                    314: 
                    315:   req.hf_request = request;
                    316:   req.hf_arg_len = cmdlen;
                    317:   req.hf_rsp_len = resplen;
                    318: 
                    319:   if (cmdlen)                  /* if arg structure to pass    */
                    320:     {
                    321:       size = sizeof (struct hfctlreq) + cmdlen;
                    322:       if ((p.c = malloc(size)) == NULL) /* malloc one area            */
                    323:        return (-1);
                    324: 
                    325:       memcpy (p.c, &req, sizeof (req)); /* copy CTL REQ struct         */
                    326:       memcpy (p.c + sizeof (req), cmd, cmdlen); /* copy arg struct     */
                    327:     }
                    328:   else
                    329:     {
                    330:       p.req = &req;            /* otherwise use only CTL REQ  */
                    331:       size = sizeof (req);
                    332:     }
                    333: 
                    334:   /* write request to terminal   */
                    335:   if (write(fd,p.c,size) == -1) return (-1);
                    336:   if (p.req != &req)           /* free if allocated           */
                    337:     free (p.c);
                    338:   return (0);
                    339: 
                    340: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.