/* Public domain. */

#include "sessutil.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#ifdef BSD
#include <limits.h>
#endif
#include <stdio.h>
extern char *ttyname();
extern long lseek();
extern char *getenv();

/* Will have to change ttyn indices if DEVSTY changes. */

int pty_sessdir(uid)
int uid;
{
 char foo[50];
 char *ho;

 if (!(ho = getenv("HOME")))
   return -1;
 (void) sprintf(foo,"%s/.pty/%d",ho,uid);
 return chdir(foo);
}

int pty_get_sess(fd,uid,ps)
int fd;
int uid;
struct pty_session *ps;
{
 char *ttyn;

 if (ttyn = ttyname(fd))
   return pty_get_sessbyext(ttyn[8],ttyn[9],uid,ps);
 return -1;
}

int pty_get_sessbyext(ext1,ext2,uid,ps)
char ext1;
char ext2;
int uid;
struct pty_session *ps;
{
 char foo[50];
 int fdsess;
 char *ho;

 if (!(ho = getenv("HOME")))
   return -1;

 ps->ext1 = ext1;
 ps->ext2 = ext2;
 (void) sprintf(foo,"%s/.pty/%d/sess.%c%c",ho,uid,ps->ext1,ps->ext2);
 if ((fdsess = open(foo,O_RDONLY)) != -1)
  {
   if ((read(fdsess,(char *) &ps->uid,sizeof(int)) == sizeof(int))
     &&(read(fdsess,(char *) &ps->siglerpid,sizeof(int)) == sizeof(int))
     &&(read(fdsess,(char *) &ps->masterpid,sizeof(int)) == sizeof(int))
     &&(read(fdsess,(char *) &ps->slavepid,sizeof(int)) == sizeof(int)))
    {
     (void) close(fdsess);
     return 0;
    }
   (void) close(fdsess);
  }
 return -1;
}

int pty_set_sess(fd,uid,ps)
int fd;
int uid;
struct pty_session *ps;
{
 char *ttyn;
 char foo[50];
 int fdsess;
 char *ho;

 if (!(ho = getenv("HOME")))
   return -1;

 if (ttyn = ttyname(fd))
  {
   ps->ext1 = ttyn[8];
   ps->ext2 = ttyn[9];
   (void) sprintf(foo,"%s/.pty/%d/sess.%c%c",ho,uid,ps->ext1,ps->ext2);
   if ((fdsess = open(foo,O_WRONLY)) != -1)
    {
     if ((write(fdsess,(char *) &ps->uid,sizeof(int)) == sizeof(int))
       &&(write(fdsess,(char *) &ps->siglerpid,sizeof(int)) == sizeof(int))
       &&(write(fdsess,(char *) &ps->masterpid,sizeof(int)) == sizeof(int))
       &&(write(fdsess,(char *) &ps->slavepid,sizeof(int)) == sizeof(int)))
      {
       (void) close(fdsess);
       return 0;
      }
     (void) close(fdsess);
    }
  }
 return -1;
}

int pty_get_sessname(fd,uid,buf,len)
int fd;
int uid;
char *buf;
int len;
{
 char *ttyn;
 char foo[50];
 int fdsess;
 int r;
 char *ho;

 if (!(ho = getenv("HOME")))
   return -1;

 if (ttyn = ttyname(fd))
  {
   (void) sprintf(foo,"%s/.pty/%d/sess.%c%c",ho,uid,ttyn[8],ttyn[9]);
   if ((fdsess = open(foo,O_RDONLY)) != -1)
    {
     if (lseek(fdsess,(long) (4 * sizeof(int)),0) != (long) -1)
       if ((r = read(fdsess,buf,len - 1)) > 0)
	{ /* could make that != -1. This way, default session is unnamed. */
	 buf[r] = '\0';
	 (void) close(fdsess);
	 return 0;
	}
     (void) close(fdsess);
    }
  }
 return -1;
}

int pty_set_sessname(fd,uid,buf,len)
int fd;
int uid;
char *buf;
int len;
{
 char *ttyn;
 char foo[50];
 int fdsess;
 char *ho;

 if (!(ho = getenv("HOME")))
   return -1;

 if (ttyn = ttyname(fd))
  {
   (void) sprintf(foo,"%s/.pty/%d/sess.%c%c",ho,uid,ttyn[8],ttyn[9]);
   if ((fdsess = open(foo,O_WRONLY)) != -1)
    {
     if (lseek(fdsess,(long) (4 * sizeof(int)),0) != (long) -1)
       if (write(fdsess,buf,len) != -1)
	{
	 (void) close(fdsess);
	 return 0;
	}
     (void) close(fdsess);
    }
  }
 return -1;
}

int pty_get_rebyext(ext1,ext2,uid)
char ext1;
char ext2;
int uid;
{
 char foo[50];
 struct stat st;
 char *ho;

 if (!(ho = getenv("HOME")))
   return -1;

 (void) sprintf(foo,"%s/.pty/%d/re.%c%c",ho,uid,ext1,ext2);
 return stat(foo,&st);
}

int pty_set_sig(ext1,ext2,uid,ps)
char ext1;
char ext2;
int uid;
struct pty_session *ps;
{
 char foo[50];
 int fdsig;
 char *ho;

 if (!(ho = getenv("HOME")))
   return -1;

 (void) sprintf(foo,"%s/.pty/%d/sig.%c%c",ho,uid,ps->ext1,ps->ext2);
 if ((fdsig = open(foo,O_WRONLY | O_CREAT | O_TRUNC,0600)) != -1)
  {
   (void) sprintf(foo,"/dev/tty%c%c",ext1,ext2);
   if (write(fdsig,foo,11) == 11)
    {
     (void) close(fdsig);
     return 0;
    }
   (void) close(fdsig);
  }
 return -1;
}

int pty_unset_sig(uid,ps)
int uid;
struct pty_session *ps;
{
 char foo[50];
 char *ho;

 if (!(ho = getenv("HOME")))
   return -1;

 (void) sprintf(foo,"%s/.pty/%d/sig.%c%c",ho,uid,ps->ext1,ps->ext2);
 return unlink(foo);
}
