/* 
   Unix SMB/Netbios implementation.
   Version 1.9.
   Copyright (C) Andrew Tridgell 1994-1997

   This file is part of the port to OpenVMS
   Emulation routines
   Copyright (C) Eckart Meyer 1996-1997
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*	get.c
 *	V1.1			23-Nov-1995	IfN/Mey
 *
 *	Copyright E. Meyer <meyer@ifn.ing.tu-bs.de>
 *+
 * Some VMS specific routines using the various system services
 * and/or runtime libraries of VMS.
 *
 * NOTE: includes.h is *NOT* - and must not! - included here!
 */
#define const
#include <stdio.h>
#include <ssdef.h>
#include <syidef.h>
#include <jpidef.h>
#include <starlet.h>
#include <descrip.h>
#include <string.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <stdlib.h>
#include <grp.h>
#include <pwd.h>

#define	BRK$C_DEVICE	1
#define	BRK$C_USERNAME	2
#define	BRK$C_ALLUSERS	3
#define	BRK$C_ALLTERMS	4


struct itemdesc {
  short int buffer_length;
  short int item_code;
  char *buffer;
  short int *ret_length;
  };

#if 1	/* for use with samba's debugging */
extern int DEBUGLEVEL;
#define DEBUG(level,body) ((DEBUGLEVEL>=(level))?(Debug1 body):0)
int Debug1();
#else
int DEBUGLEVEL = 8;
#define DEBUG(level,body) ((DEBUGLEVEL>=(level))?(printf body):0)
#endif

char *vms_make_name(char * __name);
char *vms_get_name(char * __name);

unsigned long vms_getuid()
{
  int getuid();
  int getgid();
  unsigned long uic;

  uic = (getgid() << 16) + getuid();
  if (uic == 0x00000000L || uic == 0x00010000L || uic == 0x00010004L) {
	uic = 0;	/* Samba need SYSTEM to be 0,0 ... */
  }  
/* DEBUG (3,("vms_getuid: uid = %08X\n",uic)); */
  return(uic);
}

static char pwd[12];
char *getpass(prompt)
char * prompt;
{
   void set_echo();
   void set_noecho();

   set_noecho();
   printf("%s",prompt);
   gets(pwd);
   set_echo();
   return(pwd);
}


char *vms_getcwd(char *path, size_t size)
{
	char *getcwd(char * __path, size_t __size, int __flag);

	return(strcpy(path,vms_get_name(getcwd(path,size,0))));
}


int vms_getdechostname(char *name, int namelen)
{
   struct {
      struct itemdesc id;
      int eol;
   } itmlst;
   unsigned short int iosb[4];
   short int st, lgth, i;
   itmlst.id.item_code = SYI$_NODENAME;
   itmlst.id.buffer_length = namelen;
   itmlst.id.buffer = name;
   itmlst.id.ret_length = &lgth;
   itmlst.eol = 0;
   if ((st=sys$getsyiw(0,0,0,&itmlst,iosb,0,0)) != SS$_NORMAL) return(st);
   name[lgth] = '\0';
   for (i=0;i < lgth;i++) if ((name[i] >= 'A') && (name[i] <= 'Z')) name[i] += 'a'-'A';
   return(0);
}


int vms_getusertty(char *name, char *tty)
{
   struct {
      struct itemdesc id[3];
      int eol;
   } itmlst;
   unsigned short int iosb[4];
   char uname[12], sname[12], stty[7], *p, *q;
   short int i, st, lgth1, lgth2, lgth3;
   int pid, mode;
   for (p=name,q=uname;*p != '\0';p++,q++)
    if ((*p >= 'a') && (*p <= 'z')) *q = *p-'a'+'A'; else *q = *p;
   for (i=0;i<12-strlen(p);i++,q++) *q = ' ';
   itmlst.id[0].item_code = JPI$_TERMINAL;
   itmlst.id[0].buffer_length = 7;
   itmlst.id[0].buffer = stty;
   itmlst.id[0].ret_length = &lgth1;
   itmlst.id[1].item_code = JPI$_USERNAME;
   itmlst.id[1].buffer_length = 12;
   itmlst.id[1].buffer = sname;
   itmlst.id[1].ret_length = &lgth2;
   itmlst.id[2].item_code = JPI$_MODE;
   itmlst.id[2].buffer_length = 4;
   itmlst.id[2].buffer = (char *)&mode;
   itmlst.id[2].ret_length = &lgth3;
   itmlst.eol = 0;
   pid = -1;
   while (1) {
      if ((st=sys$getjpiw(0,&pid,0,&itmlst,iosb,0,0)) == SS$_NOMOREPROC) {
         return(-1);
      }
      if ((st == SS$_NORMAL) && (strncmp(sname,uname,12) == 0) && (mode == 3)) {
         strncpy(tty,stty,lgth1);
         tty[lgth1] = '\0';
         return(0);
      }
   }
}

int vms_sendmsguser(char *s, char *t)
{
   unsigned short int iosb[4];
   short int st, i;
   char upname[16], *p;
   struct {
      int length;
      char *ptr;
   } msgdesc, senddesc;
   strcpy(upname,t);
   for (p=upname;*p != '\0';p++) if ((*p >= 'a') && (*p <= 'z')) *p -= 'a'-'A';
   msgdesc.length = strlen(s);
   msgdesc.ptr = s;
   senddesc.length = strlen(upname);
   senddesc.ptr = upname;
   if ((st= sys$brkthruw(0,&msgdesc,&senddesc,BRK$C_USERNAME,iosb,0,0,0,0,0,0))
    != SS$_NORMAL) {
      return(-1);
   }
   return(0);
}

int vms_sendmsgtty(char *s, char *t)
{
   unsigned short int iosb[4];
   short int st;
   struct {
      int length;
      char *ptr;
   } msgdesc, senddesc;
   msgdesc.length = strlen(s);
   msgdesc.ptr = s;
   senddesc.length = strlen(t);
   senddesc.ptr = t;
   if ((st= sys$brkthruw(0,&msgdesc,&senddesc,BRK$C_DEVICE,iosb,0,0,0,0,0,0))
    != SS$_NORMAL) {
      return(-1);
   }
   return(0);
}

int vms_getdtablesize()
{
   return(30);
}

int vms_getpagesize()
{
   return(512);
}

struct group *vms_getgrent()
{
   return(NULL);
}

static struct group user_grp;
static char gr_name[32];
struct group *vms_getgrgid(gid_t gid)
{
	struct dsc$descriptor_s dsc_name;
	unsigned short namlen;
	unsigned long sts;
	unsigned long id;

	dsc_name.dsc$a_pointer = gr_name;
	dsc_name.dsc$w_length = sizeof(gr_name) - 1;
	dsc_name.dsc$b_class = DSC$K_CLASS_S;
	dsc_name.dsc$b_dtype = DSC$K_DTYPE_T;
	id = ((gid&0xFFFF) << 16) | 0xFFFF;
	sts = sys$idtoasc(id,&namlen,&dsc_name,0,0,0);
	if (!(sts&1)) return(NULL);
	gr_name[namlen] = '\0';
	user_grp.gr_name = gr_name;
	user_grp.gr_passwd = NULL;	/* not supported */
	user_grp.gr_gid = (int)gid;
	user_grp.gr_mem = NULL;		/* not supported */
	return(&user_grp);
}

struct group *vms_getgrnam(char *name)
{
   return(NULL);
}

void vms_setgrent()
{
}

void vms_endgrent()
{
}

static gid_t user_gid;
void vms_initgroups(char *name, gid_t basegid)
{
	user_gid = basegid;
}

int vms_getgroups(int gidsetsize, gid_t grouplist[])
{
	if (gidsetsize > 0) {
		grouplist[0] = user_gid;
	}
	return(1);
}

#include <iodef.h>
#include <ttdef.h>
#include <descrip.h>

static $DESCRIPTOR(termdesc, "SYS$INPUT:");
static short termchan = -1;

/************************************************************/
/* set_noecho - just a utility routine to cancel term echo  */
/************************************************************/
void set_noecho()
{
  int st;
  int buf[3];
  short int iosb[4];

  if (termchan == -1) {
     sys$assign(&termdesc,&termchan,0,0);
  }
  st = sys$qiow(0,termchan,IO$_SENSEMODE,iosb,0,0,buf,12,0,0,0,0);
  buf[1] |= TT$M_NOECHO;
  st = sys$qiow(0,termchan,IO$_SETMODE,iosb,0,0,buf,12,0,0,0,0);
}

/************************************************************/
/* set_echo - just a utility routine to start term echo     */
/************************************************************/
void set_echo()
{
  int st;
  int buf[3]; 
  short int iosb[4];

  if (termchan == -1) {
     sys$assign(&termdesc,&termchan,0,0);
  }
  st = sys$qiow(0,termchan,IO$_SENSEMODE,iosb,0,0,buf,12,0,0,0,0);
  buf[1] &= ~TT$M_NOECHO;
  st = sys$qiow(0,termchan,IO$_SETMODE,iosb,0,0,buf,12,0,0,0,0);
}

