/*
 * **********************************************************************
 * *	                                                                *
 * *                    User Name Related Routines                      *
 * *                                                                    *
 * **********************************************************************
 * File: libs/user/username.c
 *
 *                 COPYRIGHT (c) 1994, 1999, 2000  BY
 *         SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED.
 *
 */

#include <ctype.h>
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "sigtypes.h"
#include "user_lib.h"

/* ======================================================================
   Internal routine to translate and check names
*/
static UINT2 liris_op_kernel
(const char *envname_a,
 const char *username_a)
{
  char *penv ; int namelen, ii, ij ;

  /* Get user name of the process
   */
  if( NULL == username_a ) return FALSE ;
  namelen = (int)strlen( username_a ) ;
  if( 0 == namelen ) return FALSE ;

  /* Translate environment variable for list of names
   */
  penv = (char *)getenv(envname_a) ;
  if( NULL == penv ) return FALSE ;
  
  /* Perform case insensitive search for the user name within the
   * list.  Fuss is due to VMS not having the strncasecmp() routine.
   */
  for(;;) {
    while( *penv == ' ' ) penv++ ;
    for( ij=ii=0 ; ii<namelen ; ii++ ) {
      if( (penv[ii] == (char)NULL) ||
	 (toupper(penv[ii]) != toupper(username_a[ii])) ) { ij++ ; break ; }
    }
    if( (ij == 0) &&
       ( (penv[namelen] == (char)NULL) || (penv[namelen] == ' ') ) ) return TRUE ;
    while( *penv != ' ' ) { if( *penv == (char)NULL ) return FALSE ; penv++ ; }
  }
  return FALSE ;
}

/* ======================================================================
 * Return NZ if the user is an iris operator
 */
UINT2 liris_operator(const char *susername_a )
{
  UINT2 lresult;
  lresult = liris_op_kernel( "IRIS_OPERATORS", susername_a ) ;
  return lresult ;
}

/* ======================================================================
   Return NZ if the user is an iris observer
*/
UINT2 liris_observer(const char *susername_a)
{
  UINT2 lresult;
  lresult = liris_op_kernel( "IRIS_OBSERVERS", susername_a ) ;
  return lresult ;
}

/* ======================================================================
 * Return real user name (not the effective one) for this process, or
 * NULL if the name can not be determined.  Stored name is required by
 * AIX machine.  See sig_run_as_operator and sig_run_as_root for details.
 */
const char *sig_username()
{
  static char sname[20], *pname=NULL ;

  if( pname == NULL )
    {

      struct passwd *pwp ; 
      pwp = getpwuid( getuid() ) ;
      if( pwp == NULL ) {
	sig_signal( errno_to_message_va( errno, 1, "sig_username()" ) ) ;
      } else {
	strncpy( sname, pwp->pw_name, 20 ) ; pname = sname ;
      }
    
    }
  return( pname ) ;
}

/* ======================================================================
 * Logical function returning NZ if the user is the 'root' user for the
 * particular system.  Exactly who this is may vary...
 */
UINT2 lsig_user_is_root() {
  return( 0 == strcmp( sig_username(), "root" ) ) ;
}
