home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / pty4 / part03 / ptyget.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-19  |  3.7 KB  |  155 lines

  1. #ifdef IRIS_UGH_PTYS
  2. #include <fcntl.h>
  3. #include <sys/types.h>
  4. #include <sys/sysmacros.h>
  5. #include <sys/stat.h>
  6. #include <stdio.h>
  7. #endif
  8. #include <sys/file.h>
  9. #include <errno.h>
  10. extern int errno;
  11. #include "ptyget.h"
  12. #include "config/ptyext.h"
  13. #include "config/devmty.h"
  14. #include "config/devsty.h"
  15. #include "ptysecure.h"
  16.  
  17. static int gcd(x,y) /* assumes both nonnegative */
  18. int x; int y;
  19. {
  20.  int t;
  21.  while (x && y) { t = x % y; x = y; y = t; }
  22.  return x ? x : y;
  23. }
  24.  
  25. int ungetpty(fdmaster,fdslave,ext)
  26. int fdmaster;
  27. int fdslave;
  28. char *ext;
  29. {
  30. #ifdef IRIS_UGH_PTYS
  31.  return 0; /*XXX*/
  32. #endif
  33.  /*XXXX*/
  34.  ptyunsecure(fdmaster,fdslave,ext);
  35.  /* XXX: close fdmaster and fdslave? nah */
  36. }
  37.  
  38. static char fnmty[sizeof(DEVMTY) + 2] = DEVMTY;
  39. static char fnsty[sizeof(DEVSTY) + 2] = DEVSTY;
  40.  
  41. static char pty1[] = PTYEXT1;
  42. static char pty2[] = PTYEXT2;
  43. #define pty1len (sizeof(pty1) - 1)
  44. #define pty2len (sizeof(pty2) - 1)
  45.  
  46. static int bankok[pty1len]; /* must be initialized to 0! */
  47.  
  48. /* not reentrant */
  49. int getfreepty(fdmaster,fdslave,ext,r1,r2,eachpty,flagxchown,allowinsecure)
  50. int *fdmaster;
  51. int *fdslave;
  52. char *ext;
  53. int r1;
  54. int r2; /* set both r1 and r2 to 0 for the standard searching order */
  55. int (*eachpty)();
  56. int flagxchown;
  57. int allowinsecure;
  58. {
  59.  int start;
  60.  int increment;
  61.  int pos;
  62.  int p1;
  63.  int fdmty;
  64.  int fdsty;
  65.  
  66. #ifdef IRIS_UGH_PTYS /* XXX: needless to say, deprecated */
  67.  
  68. char foo[200]; int ptynum; struct stat statmty;
  69. if (eachpty("xx") == -1) return -1;
  70. fdmty = open("/dev/ptc",O_RDWR | O_NDELAY);
  71. if (fdmty == -1) return -1;
  72. if (fstat(fdmty,&statmty) == -1) { close(fdmty); return -1; }
  73. ptynum = minor(statmty.st_rdev);
  74. sprintf(foo,"/dev/ttyq%d",ptynum);
  75. fdsty = open(foo,O_RDWR);
  76. *fdmaster = fdmty; *fdslave = fdsty;
  77. ext[0] = 'a' + ptynum / 26;
  78. ext[1] = 'a' + ptynum % 26;
  79. return 0;
  80.  
  81. #endif
  82.  
  83.  /* XXX: Here would be a good spot to include pty limits, say through */
  84.  /* the file PTYDIR/LIMITS. Lines of the form user group num, saying */
  85.  /* that user in that group is limited to num ptys, with * for all. */
  86.  /* All pty use would have to be logged somewhere. Anyway, with a */
  87.  /* streams-based pty, there wouldn't be much point to limits. */
  88.  
  89.  pos = pty1len * pty2len;
  90.  start = r1 % pos; if (start < 0) start += pos;
  91.  increment = r2 % pos; if (increment < 0) increment += pos;
  92.  
  93.  while (gcd(increment,pos) != 1)
  94.    ++increment; /* note that this weights some increments more heavily */
  95.  
  96.  fnmty[sizeof(DEVMTY) + 1] = 0;
  97.  fnsty[sizeof(DEVSTY) + 1] = 0;
  98.  
  99.  pos = start;
  100.  do
  101.   {
  102.    p1 = pos / pty2len;
  103.    fnmty[sizeof(DEVMTY) - 1] = pty1[p1];
  104.    if (!bankok[p1])
  105.     {
  106.      fnmty[sizeof(DEVMTY)] = pty2[0];
  107.      if (access(fnmty,F_OK) == -1)
  108.        bankok[p1] = -1;
  109.      else
  110.        bankok[p1] = 1;
  111.     }
  112.    if (bankok[p1] == 1) /* okay, we know bank exists. */
  113.     {
  114.      fnsty[sizeof(DEVMTY)] = fnmty[sizeof(DEVMTY)] = pty2[pos % pty2len];
  115.      fnsty[sizeof(DEVSTY) - 1] = pty1[p1];
  116.      if (eachpty(fnmty + sizeof(DEVMTY) - 1) == -1)
  117.        return -1;
  118.      do
  119.        fdmty = open(fnmty,O_RDWR);
  120.      while ((fdmty == -1) && (errno == EINTR));
  121.      if (fdmty != -1)
  122.       {
  123.        do
  124.          fdsty = open(fnsty,O_RDWR);
  125.        while ((fdsty == -1) && (errno == EINTR));
  126.        if (fdsty == -1)
  127.      close(fdmty); /* XXX: warning that slave isn't openable? */
  128.        else
  129.     {
  130.      setnonblock(fdmty); /*XXX*/
  131.      ext[0] = pty1[p1];
  132.      ext[1] = pty2[pos % pty2len];
  133.      /* Got both sides of the tty open! Now comes the tricky part. */
  134.      if (ptysecure(&fdmty,&fdsty,ext,fnmty,fnsty,flagxchown,allowinsecure) == -1)
  135.       {
  136.        /* XXX: warning of security violation? */
  137.       }
  138.      else
  139.       {
  140.        unsetnonblock(fdmty); /*XXX*/
  141.        /* It's ours. */
  142.        *fdmaster = fdmty;
  143.        *fdslave = fdsty;
  144.        return 0;
  145.       }
  146.     }
  147.       }
  148.     }
  149.    pos = (pos + increment) % (pty1len * pty2len);
  150.   }
  151.  while (pos != start);
  152.  
  153.  return -1; /* all unopenable? yikes */
  154. }
  155.