Annotation of GNUtools/emacs/src/hftctl.c, revision 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.