################################################################
function usagemsg_id_k93 {
  print -- "
Program: id_k93

The id_k93 function writes to standard output a message containing the 
system identifications (ID) for a specified user.  The system IDs 
are numbers which identify users and user groups to the system.

Usage: ${1##*/} [-vV] [ { -G | -g [ -r ] | -u [ -r ] } [ -n ] ] [ User ]

    Where:
      -v = Verbose mode
      -V = Very Verbose mode
      -G = Specifies that the id_k93 function write the effective, real, 
           and supplementary group IDs only.  If there are multiple 
           entries for the effective, real, or supplementary IDs, they 
           are separated by a space and placed on the same line.
      -g = Specifies that the id_k93 function write only the group ID.
      -u = Specifies that the id_k93 function write only the user ID.
      -r = Specifies that the id_k93 function write the real ID instead of 
           the effective ID. This flag can be invoked with either the -g 
           flag to write the real group ID, or the -u flag to write the 
           real user ID.
      -n = Specifies that the id_k93 function outputs the name, instead 
           of the ID number, when it is specified with the -G, -g, and 
           -u flags.

    User = Specifies the login name of a user for the id_k93 function. 
           If no user is specified, the user invoking the id_k93 function 
           is the default.

Author: Dana French (dfrench@mtxia.com)    Copyright 2004

\"AutoContent\" enabled"
  return 0
}
################################################################
#### 
#### Description:
#### 
#### The id_k93 function writes to standard output a message
#### containing the system identifications (ID) for a
#### specified user.  The system IDs are numbers which
#### identify users and user groups to the system. 
#### 
#### Assumptions:
#### 
#### Dependencies:
#### 
#### Products:
#### 
#### Configured Usage:
#### 
#### Details:
#### 
################################################################
function id_k93 {
  typeset TRUE="0"
  typeset FALSE="1"
  typeset VERBOSE="${FALSE}"
  typeset VERYVERB="${FALSE}"
  typeset ONLYGID="${FALSE}"
  typeset ONLYGRP="${FALSE}"
  typeset ONLYUSR="${FALSE}"
  typeset REALIDS="${FALSE}"
  typeset NAMEOUT="${FALSE}"
  typeset USERNAME
  typeset PWDUSER
  typeset PWDPWD
  typeset PWDUID
  typeset PWDGID
  typeset PWDGECOS
  typeset PWDHOME
  typeset PWDSHELL
  typeset EUID
  typeset EGID

  while getopts ":GgurnvV" OPTION
  do
    case "${OPTION}" in
        'G') ONLYGID="${TRUE}";;
        'g') ONLYGRP="${TRUE}";;
        'u') ONLYUSR="${TRUE}";;
        'r') REALIDS="${TRUE}";;
        'n') NAMEOUT="${TRUE}";;
        'v') VERBOSE="${TRUE}";;
        'V') VERYVERB="${TRUE}";;
        '?') usagemsg_id_k93 "${0}" && return 1 ;;
    esac
  done
 
  shift $(( ${OPTIND} - 1 ))

################################################################

####
#### Obtain the target username from the first command line
#### argument, if NULL determine the target username from
#### the existing environment variable LOGIN.  If this value
#### is NULL use LOGNAME, if still NULL use USER.  If still
#### NULL exit with an error message. 
####

  USERNAME="${1:-${LOGIN}}"
  USERNAME="${USERNAME:-${LOGNAME}}"
  USERNAME="${USERNAME:-${USER}}"
  USERNAME="${USERNAME:?ERROR: Unable to determine user name}"

#### 
#### Read each line of the /etc/passwd file and match the
#### target username against each username listed in the
#### file.  When a match is found, save the UID and GID
#### values for later use and stop processing the file. 
#### 

  while IFS=":" read -- PWDUSER PWDPWD PWDUID PWDGID PWDGECOS PWDHOME PWDSHELL
  do
    if [[ "_${PWDUSER}" = "_${USERNAME}" ]]
    then
        EUID="${PWDUID}"
        EGID="${PWDGID}"
        break
    fi
  done < /etc/passwd

  if [[ "_${EUID}" == "_" ]] || [[ "_${EGID}" == "_" ]]
  then
      print -u 2 -- "# ${0}: ${USERNAME}: No such user"
      return 1
  fi

#### If the "-u" option was entered on the command line,
#### output the UID number and exit the function.

  (( ONLYUSR == TRUE && NAMEOUT == FALSE )) && print "${EUID}" && return 0

#### If the "-u" and "-n" options were entered on the
#### command line, output the username and exit the function. 

  (( ONLYUSR == TRUE && NAMEOUT == TRUE )) && print "${USERNAME}" && return 0

#### If the "-g" option was entered on the command line,
#### output the GID number and exit the function.

  (( ONLYGRP == TRUE && NAMEOUT == FALSE )) && print "${EGID}" && return 0

#### 
#### Read each line from the /etc/group file to determine the
#### group name associated with the GID number extracted from
#### the user record in the /etc/passwd file.  Assign this
#### group name as the primary group.
#### 

  while IFS=":" read -- GRPNAME GRPPWD GRPGID GRPUSERS
  do
    if [[ "_${EGID}" = "_${GRPGID}" ]]
    then
        PRIMARYGROUP="${GRPNAME}"
        break
    fi
  done < /etc/group

#### If the "-g" and "-n" options were entered on the
#### command line, output the primary group name and exit the function.

  (( ONLYGRP == TRUE && NAMEOUT == TRUE )) && print "${PRIMARYGROUP}" && return 0

#### 
#### To ensure empty arrays, incase multiple user names are
#### allowed on the command line, unset the arrays used to
#### contain the list of secondary group names and GID
#### numbers. 
#### 

  unset GRPNAMLIST
  unset GRPGIDLIST

#### 
#### Use a counter to keep track of the GID order in the
#### array.  Since the GID number may be greater than the
#### allowed size of a korn shell array, a separate counter
#### is used.
#### 

  CNT=0

#### 
#### Loop through each line of the /etc/group file and
#### determine what groups the username is associated with. 
#### When a group is found, store the group name and the GID
#### number in separate arrays to preserve the numerical
#### order.
#### 

  while IFS=":" read -- GRPNAME GRPPWD GRPGID GRPUSERS
  do
    (( GRPGID == EGID )) && continue
    if [[ "_${GRPUSERS}" = _${USERNAME} ]] ||
       [[ "_${GRPUSERS}" = _${USERNAME},* ]] ||
       [[ "_${GRPUSERS}" = _*,${USERNAME},* ]] ||
       [[ "_${GRPUSERS}" = _*,${USERNAME} ]]
    then
        GRPNAMLIST[CNT]="${GRPNAME}"
        GRPGIDLIST[CNT]="${GRPGID}"
        (( CNT++ ))
    fi
  done < /etc/group

#### If the '-G' option was entered on the command line,
#### print the GID number of the primary group.  If the '-n'
#### option was also used, print the primary group name,
#### otherwise print the normal 'id' command output. 

  if (( ONLYGID == TRUE && NAMEOUT == FALSE ))
  then
      print -r -n -- "${EGID}"
  elif (( ONLYGID == TRUE && NAMEOUT == TRUE ))
  then
      print -r -n -- "${PRIMARYGROUP}"
  else
      print -r -n -- "uid=${EUID}(${USERNAME}) gid=${EGID}(${PRIMARYGROUP})"
      (( ${#GRPGIDLIST[*]} != 0 )) && print -r -n -- " groups="
  fi
  
#### 
#### Loop through each stored secondary GID associated with the 
#### user and print as specified by the command line options.
#### 

  COMMA=""
  for GRP in "${!GRPGIDLIST[@]}"
  do

#### 
#### If the '-G' option was specified on the command line,
#### the print the secondary group GID number.  If the '-n'
#### option was also specified, print the secondary group
#### name.  Otherwise print the normal 'id' command output.
#### 

    if (( ONLYGID == TRUE && NAMEOUT == FALSE ))
    then
      print -r -n -- " ${GRPGIDLIST[${GRP}]}"
    elif (( ONLYGID == TRUE && NAMEOUT == TRUE ))
    then
      print -r -n -- " ${GRPNAMLIST[${GRP}]}"
    else
      print -r -n "${COMMA}${GRPGIDLIST[${GRP}]}(${GRPNAMLIST[${GRP}]})"
      COMMA=","
    fi
  done  

#### Up to this point, no CR characters have been printed,
#### since all output is now complete, send a CR character.
  
  print

#### Return to the calling function with a successful
#### return code.

  return 0
}
################################################################

#### Call the id function with all command line arguments.

id_k93 "${@}"