v29i128: pidentd-2.7 - Portable Ident Daemon, V2.7, Part05/09

1 view
Skip to first unread message

Peter Eriksson

unread,
Sep 8, 1996, 3:00:00 AM9/8/96
to

Submitted-By: pe...@ifm.liu.se (Peter Eriksson)
Posting-Number: Volume 29, Issue 128
Archive-Name: pidentd-2.7/part05

#!/bin/sh
# This is part 05 of a multipart archive.
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
set `$dir/gettext --version 2>&1`
if test "$3" = GNU
then
gettext_dir=$dir
fi
fi
if test "$locale_dir" = FAILED && test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
echo=echo
else
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
shar_touch=touch
else
shar_touch=:
echo
$echo 'WARNING: not restoring timestamps. Consider getting and'
$echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh08724; then
$echo 'x -' 'creating lock directory'
else
$echo 'failed to create lock directory'
exit 1
fi
# ============= pidentd-2.7/src/kernel/4.3bsd.c ==============
if test ! -d 'pidentd-2.7'; then
$echo 'x -' 'creating directory' 'pidentd-2.7'
mkdir 'pidentd-2.7'
fi
if test ! -d 'pidentd-2.7/src'; then
$echo 'x -' 'creating directory' 'pidentd-2.7/src'
mkdir 'pidentd-2.7/src'
fi
if test ! -d 'pidentd-2.7/src/kernel'; then
$echo 'x -' 'creating directory' 'pidentd-2.7/src/kernel'
mkdir 'pidentd-2.7/src/kernel'
fi
if test -f 'pidentd-2.7/src/kernel/4.3bsd.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/4.3bsd.c' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/kernel/4.3bsd.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/4.3bsd.c' &&
/*
** kernel/bsd43.c Low level kernel access functions for 4.3BSD
**
** This program is in the public domain and may be used freely by anyone
** who wants to.
**
** Last update: 17 March 1993
**
** Please send bug fixes/bug reports to: Peter Eriksson <p...@lysator.liu.se>
*/
X
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <nlist.h>
#include <pwd.h>
#include <signal.h>
#include <syslog.h>
X
#include "kvm.h"
X
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
X
#include <sys/socketvar.h>
X
#define KERNEL
X
#include <sys/file.h>
X
#if 0
X
#include <sys/time.h>
#include <sys/vmmac.h>
#include <sys/proc.h>
#include <sys/dir.h>
X
#include <fcntl.h>
X
#ifdef DIRBLKSIZ
# undef DIRBLKSIZ
#endif
#include <sys/user.h>
X
#include <sys/wait.h>
X
#else
X
#include <sys/dir.h> /* tmk */
#include <sys/user.h> /* tmk */
/*#include <sys/time.h>
*/
#include <sys/vmmac.h>
#include <sys/proc.h>
/*#include <sys/dir.h>
*/
#include <fcntl.h>
X
#ifdef DIRBLKSIZ
# undef DIRBLKSIZ
#endif
/*#include <sys/user.h>
*/
#endif
X
#ifdef KERNEL
#undef KERNEL
#endif
X
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
X
#include <netinet/in_systm.h>
#include <netinet/ip.h>
X
#include <netinet/in_pcb.h>
X
#include <netinet/tcp.h>
#include <netinet/ip_var.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
X
#include <arpa/inet.h>
X
#include "identd.h"
#include "error.h"
X
X
extern void *calloc();
extern void *malloc();
X
X
struct nlist nl[] =
{
#define N_FILE 0
#define N_NFILE 1
#define N_TCB 2
X
X { "_file" },
X { "_nfile" },
X { "_tcb" },
X { "" }
};
X
static kvm_t *kd;
X
static struct file *xfile;
static int nfile;
X
static struct inpcb tcb;
X
X
int k_open()
{
X /*
X ** Open the kernel memory device
X */
X if (!(kd = kvm_open(path_unix, path_kmem, NULL, O_RDONLY, NULL)))
X ERROR("main: kvm_open");
X
X /*
X ** Extract offsets to the needed variables in the kernel
X */
X if (kvm_nlist(kd, nl) != 0)
X ERROR("main: kvm_nlist");
X
X return 0;
}
X
X
/*
** Get a piece of kernel memory with error handling.
** Returns 1 if call succeeded, else 0 (zero).
*/
static int getbuf(addr, buf, len, what)
X long addr;
X char *buf;
X int len;
X char *what;
{
X if (kvm_read(kd, addr, buf, len) < 0)
X {
X if (syslog_flag)
X syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
X addr, len, what);
X
X return 0;
X }
X
X return 1;
}
X
X
X
/*
** Traverse the inpcb list until a match is found.
** Returns NULL if no match.
*/
static struct socket *
X getlist(pcbp, faddr, fport, laddr, lport)
X struct inpcb *pcbp;
X struct in_addr *faddr;
X int fport;
X struct in_addr *laddr;
X int lport;
{
X struct inpcb *head;
X
X if (!pcbp)
X return NULL;
X
X
X head = pcbp->inp_prev;
X do
X {
X if ( pcbp->inp_faddr.s_addr == faddr->s_addr &&
X pcbp->inp_laddr.s_addr == laddr->s_addr &&
X pcbp->inp_fport == fport &&
X pcbp->inp_lport == lport )
X return pcbp->inp_socket;
X } while (pcbp->inp_next != head &&
X getbuf((long) pcbp->inp_next,
X pcbp,
X sizeof(struct inpcb),
X "tcblist"));
X
X return NULL;
}
X
X
X
/*
** Return the user number for the connection owner
*/
int k_getuid(faddr, fport, laddr, lport, uid)
X struct in_addr *faddr;
X int fport;
X struct in_addr *laddr;
X int lport;
X int *uid;
{
X long addr;
X struct proc *pp;
X struct user *up;
X int offset;
X struct socket *sockp;
X int i;
X
X /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
X if (!getbuf(nl[N_NFILE].n_value, &nfile, sizeof(nfile), "nfile"))
X return -1;
X
X if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
X return -1;
X
X xfile = (struct file *) calloc(nfile, sizeof(struct file));
X if (!xfile)
X ERROR2("k_getuid: calloc(%d,%d)", nfile, sizeof(struct file));
X
X if (!getbuf(addr, xfile, sizeof(struct file)*nfile, "file[]"))
X return -1;
X
X /* -------------------- TCP PCB LIST -------------------- */
X if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb"))
X return -1;
X
X tcb.inp_prev = (struct inpcb *) nl[N_TCB].n_value;
X sockp = getlist(&tcb, faddr, fport, laddr, lport);
X
X if (!sockp)
X return -1;
X
X /* -------------------- SCAN PROCESS TABLE ------------------- */
X if (kvm_setproc(kd) < 0)
X ERROR("k_getuid: kvm_setproc() failed");
X
X while (pp = kvm_nextproc(kd))
X {
X if (pp->p_stat == 0)
X continue;
X
X if (pp->p_stat == SZOMB)
X continue;
X
X /* ------------------- GET U_AREA FOR PROCESS ----------------- */
X if ((up = kvm_getu(kd, pp)) == NULL)
X ERROR1("k_getuid: kvm_getu() failed for process %d", pp->p_pid);
X
X /* ------------------- SCAN FILE TABLE ------------------------ */
X for (i = up->u_lastfile; i >= 0; i--)
X {
X if (up->u_ofile[i] == 0)
X continue;
X
X offset = up->u_ofile[i] - (struct file *) addr;
X if (xfile[offset].f_type == DTYPE_SOCKET &&
X (struct socket *) xfile[offset].f_data == sockp)
X {
#ifdef TAHOE
X *uid = up->u_ruid;
#else
X *uid = pp->p_ruid;
#endif
X return 0;
X } /* if */
X } /* for -- ofiles */
X } /* for -- proc */
X
X return -1;
}
X
SHAR_EOF
$shar_touch -am 1110211693 'pidentd-2.7/src/kernel/4.3bsd.c' &&
chmod 0644 'pidentd-2.7/src/kernel/4.3bsd.c' ||
$echo 'restore of' 'pidentd-2.7/src/kernel/4.3bsd.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/kernel/4.3bsd.c:' 'MD5 check failed'
40b3ebdbd8a80f0db708af177cdb96ea pidentd-2.7/src/kernel/4.3bsd.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/4.3bsd.c'`"
test 5106 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/kernel/4.3bsd.c:' 'original size' '5106,' 'current size' "$shar_count!"
fi
fi
# ============= pidentd-2.7/src/kernel/aix.c ==============
if test -f 'pidentd-2.7/src/kernel/aix.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/aix.c' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/kernel/aix.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/aix.c' &&
/*
** 941026: Harlan Stenn <har...@pfcs.com> Hacked mercilessly from:
**
** aixident -- AIX identification daemon
** version 1.0
**
** Copyright 1992 by Charles M. Hannum.
**
** Permission is granted to copy, modify, and use this program in any way,
** so long as the above copyright notice, this permission notice, and the
** warranty disclaimer below remain on all copies, and are unaltered.
**
** aixident 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.
*/
#include <sys/types.h>
X
#include <stdlib.h>
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <syslog.h>
X
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/vfs.h>
#include <net/route.h>
#include <netinet/in.h>
X
#if defined(_AIX4)
#include <netinet/ip.h>
#endif /* defined(_AIX4) */
X
#include <netinet/in_pcb.h>
#include <arpa/inet.h>
X
#define _KERNEL 1
#include <sys/file.h>
#undef _KERNEL
#include <procinfo.h>
X
#if defined(_AIX4)
#define u_maxofile U_maxofile
#define u_ufd U_ufd
#endif /* defined(_AIX4) */
X
#include "identd.h"
#include "error.h"
#include "paths.h"
X
int kmem;
X
int kread ();
X
int k_open()
{
X if ((kmem = open (_PATH_KMEM, O_RDONLY)) == -1)
X ERROR("main: k_open");
X
X return 0;
}
X
/*
** Return the user number for the connection owner
*/
int k_getuid(faddr, fport, laddr, lport, uid
#ifdef ALLOW_FORMAT
X , pid, cmd, cmd_and_args
#endif
X )
X struct in_addr *faddr;
X int fport;
X struct in_addr *laddr;
X int lport;
X int *uid;
#ifdef ALLOW_FORMAT
X int *pid;
X char **cmd,**cmd_and_args;
#endif
{
X struct sockaddr_in foreign, local;
X int max_procs = 64,
X num_procs, fd;
X struct procinfo *procinfo;
X struct user user;
X struct file *filep, file;
X struct socket *socketp, socket;
X struct protosw *protoswp, protosw;
X struct domain *domainp, domain;
X struct inpcb *inpcbp, inpcb;
X struct passwd *passwd;
X static char argline[4096],progname[256];
X char *cp;
X
X while ((procinfo = (struct procinfo *)
X malloc ((size_t) (max_procs * sizeof (*procinfo)))) &&
X (num_procs = getproc (procinfo, max_procs,
X sizeof (*procinfo))) == -1 &&
X errno == ENOSPC) {
X max_procs <<= 1;
X free (procinfo);
X }
X
X if (! procinfo) {
X if (syslog_flag)
X (void) syslog (LOG_ERR, "out of memory allocating %ld procinfo structs\n",
X max_procs);
X return -1;
X }
X
X for (; num_procs; num_procs--, procinfo++) {
X
X if (procinfo->pi_stat == 0 || procinfo->pi_stat == SZOMB)
X continue;
X
X if (getuser (procinfo, sizeof (*procinfo), &user, sizeof (user)))
X continue;
X
X for (fd = 0; fd < user.u_maxofile; fd++) {
X
X if (! (filep = user.u_ufd[fd].fp))
X continue;
X
X if (kread ((off_t) filep, (char *) &file, sizeof (file))) {
X if (syslog_flag)
X (void) syslog (LOG_ERR, "can't read file struct from %#x",
X (unsigned) filep);
X return -1;
X }
X
X if (file.f_type != DTYPE_SOCKET)
X continue;
X
X if (! (socketp = (struct socket *) file.f_data))
X continue;
X
X if (kread ((off_t) socketp, (char *) &socket, sizeof (socket))) {
X if (syslog_flag)
X (void) syslog (LOG_ERR, "can't read socket struct from %#x",
X (unsigned) socketp);
X return -1;
X }
X
X if (! (protoswp = socket.so_proto))
X continue;
X
X if (kread ((off_t) protoswp, (char *) &protosw, sizeof (protosw))) {
X if (syslog_flag)
X (void) syslog (LOG_ERR, "can't read protosw struct from %#x",
X (unsigned) protoswp);
X return -1;
X }
X
X if (protosw.pr_protocol != IPPROTO_TCP)
X continue;
X
X if (! (domainp = protosw.pr_domain))
X continue;
X
X if (kread ((off_t) domainp, (char *) &domain, sizeof (domain))) {
X if (syslog_flag)
X (void) syslog (LOG_ERR, "can't read domain struct from %#x",
X (unsigned) domainp);
X return -1;
X }
X
X if (domain.dom_family != AF_INET)
X continue;
X
X if (! (inpcbp = (struct inpcb *) socket.so_pcb))
X continue;
X
X if (kread ((off_t) inpcbp, (char *) &inpcb, sizeof (inpcb))) {
X if (syslog_flag)
X (void) syslog (LOG_ERR, "can't read inpcb struct from %#x",
X (unsigned) inpcbp);
X return -1;
X }
X
X if (socketp != inpcb.inp_socket)
X continue;
X
X if (inpcb.inp_faddr.s_addr != faddr->s_addr ||
X inpcb.inp_fport != fport ||
X inpcb.inp_laddr.s_addr != laddr->s_addr ||
X inpcb.inp_lport != lport)
X continue;
X
X *uid = procinfo->pi_uid;
#ifdef ALLOW_FORMAT
X *pid = procinfo->pi_pid;
X bzero(argline,sizeof(argline));
X getargs(procinfo,sizeof(*procinfo),argline,sizeof(argline));
X strcpy(progname,argline);
X *cmd = progname;
X for (cp = argline; *cp != '\0';) {
X cp += strlen(cp);
X *cp++ = ' ';
X }
X *cmd_and_args = argline;
#endif
X
X return 0;
X }
X }
X
X return -1;
}
X
int
kread (addr, buf, len)
X off_t addr;
X char *buf;
X int len;
{
X int br;
X
X if (lseek (kmem, addr, L_SET) == (off_t) -1)
X return (-1);
X
X br = read(kmem, buf, len);
X
X return ((br == len) ? 0 : 1);
}
X
X
SHAR_EOF
$shar_touch -am 0812002696 'pidentd-2.7/src/kernel/aix.c' &&
chmod 0644 'pidentd-2.7/src/kernel/aix.c' ||
$echo 'restore of' 'pidentd-2.7/src/kernel/aix.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/kernel/aix.c:' 'MD5 check failed'
a2e2bb20500fa94adfb9621b0a4b9300 pidentd-2.7/src/kernel/aix.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/aix.c'`"
test 5074 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/kernel/aix.c:' 'original size' '5074,' 'current size' "$shar_count!"
fi
fi
# ============= pidentd-2.7/src/kernel/alpha3.c ==============
if test -f 'pidentd-2.7/src/kernel/alpha3.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/alpha3.c' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/kernel/alpha3.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/alpha3.c' &&
/*
X * 16 Apr 96 - Changes by Paul Szabo <p...@maths.usyd.edu.au>
X *
X * May 23, 1994 - Modified by Allan E. Johannesen (a...@wpi.edu) from code
X * kindly provided by Digital during the Beta test of Digital Alpha AXP OSF/1
X * 3.0 when WPI discovered that the file structures had changed. Prior to 3.0,
X * OSF/1 ident support had only needed 64-bit modifications to the `other.c'
X * kernel routine (those mods done at WPI during the initial OSF/1 Beta tests).
X *
X * NOTE:
X * This tool is NOT part of DEC OSF/1 and is NOT a supported product.
X *
X * BASED ON code provided by
X * Aju John, UEG, Digital Equipment Corp. (ZK3) Nashua, NH.
X *
X * The following is an **unsupported** tool. Digital Equipment Corporation
X * makes no representations about the suitability of the software described
X * herein for any purpose. It is provided "as is" without express or implied
X * warranty.
X *
X * BASED ON:
X * PADS program by Stephen Carpenter, UK UNIX Support, Digital Equipment Corp.
X * */
X
/*
X * Multiple, almost simultaneous identd requests were causing a
X * 'kernel panic' crash on our 2-CPU 2100 server running OSF 3.2C
X * (though no such problems were seen on Alphastations). We were
X * initially told to try patch 158. When that did not cure the
X * problem, Digital service came up with the following on 9 May 96:
X *
X * > The following came from an outage in the states about the same thing.
X * >
X * > The active program was "identd" which is a freeware
X * > program that identifies the user who is opening a port on the system.
X * >
X * > Careful analysis shows that the identd program is causing the crash by
X * > seeking to an invalid address in /dev/kmem. The program, identd reads
X * > through /dev/kmem looking for open files that are sockets, which then send
X * > pertainent information back to the other end. In this case, the socket has
X * > gone away before the read has been performed thereby causing a panic.
X * >
X * > identd reading /dev/kmem, causing a fault on the kernel stack guard pages
X * > which in turn cause the kernel to panic. To fix this problem, set the
X * > following in /etc/sysconfigtab:
X * >
X * > vm:
X * > kernel-stack-guard-pages = 0
X * >
X * > could you try this and see if that fixes your problem.
X *
X * This has fixed our problem, though I am worried what other
X * effects this may have.
X *
X * These crashes occured while we had k_open in the parent process (in
X * src/identd.c): the file pointers would have been all over the place.
X * Now that we have k_open in the child process (in src/parse.c) we may
X * not have a crash anyway...
X */
X
#include <stdlib.h>
#include <stdio.h>
#include <nlist.h>
#include <sys/types.h>
#define SHOW_UTT
#include <sys/user.h>
#define KERNEL_FILE
#include <sys/file.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/in_pcb.h>
X
#include <alloca.h>
X
#include "identd.h"
#include "error.h"
#include "kvm.h"
X
/* The following is in <sys/proc.h>, but only if _KERNEL is defined */
struct pid_entry {
X pid_t pe_pid; /* process id */
X int pe_generation; /* checks for struct re-use */
X struct proc *pe_proc; /* pointer to this pid's proc */
X union {
X struct pid_entry *peu_nxt; /* next entry in free list */
X struct {
X int peus_pgrp; /* pid is pgrp leader? */
X int peus_sess; /* pid is session leader? */
X } peu_s;
X } pe_un;
};
X
/* The following is in <sys/proc.h>, but only if _KERNEL is defined */
#define PID_INVALID(pid) ((pid_t)(pid) < 0 || (pid_t)(pid) > (pid_t)PID_MAX)
X
/* The following is in <sys/ucred.h>, but only if _KERNEL is defined */
#define INVALID_UID(uid) ((uid_t)(uid) < 0 || (uid_t)(uid) > (uid_t)UID_MAX)
X
X
#ifdef NOFILE_IN_U /* more than 64 open files per process ? */
# define OFILE_EXTEND
#else
# define NOFILE_IN_U NOFILE
#endif
X
X
#define BUFLEN 1024 /* buffer length */
X
#ifdef DEBUG
#define sysl(a,b) printf(a, b); printf("\n");
#else /* DEBUG */
#ifdef STRONG_LOG
#define sysl(a,b) if (syslog_flag) { syslog(LOG_INFO, a, b); }
#else
#define sysl(a,b)
#endif
#endif /* DEBUG */
X
X
#define ZAP(x,fmt,err) \
X if (x) \
X { \
X sysl(fmt, err) \
X return (-1); \
X }
X
#ifdef DEBUG
#define SETZAP(x,lev,fmt,err1,err2,err3) \
X if (x) \
X { \
X printf ("zap to level %d: ", lev); printf (fmt, err1, err2, err3); printf ("\n"); \
X if (lev > zaplevel) \
X { \
X sprintf (zapmess, fmt, err1, err2, err3); \
X zaplevel = lev; \
X printf ("zap level set to %d\n", zaplevel); \
X } \
X continue; \
X }
#else /* DEBUG */
#define SETZAP(x,lev,fmt,err1,err2,err3) \
X if (x) \
X { \
X if (lev > zaplevel && syslog_flag) \
X { \
X sprintf (zapmess, fmt, err1, err2, err3); \
X zaplevel = lev; \
X } \
X continue; \
X }
#endif /* DEBUG */
X
X
struct nlist name_list[] = {
#define N_PIDTAB 0
X { "_pidtab" },
#define N_NPID 1
X { "_npid" },
X { 0 }
};
X
static kvm_t *kd;
X
X
int k_open()
{
X if (!(kd = kvm_open("/vmunix", "/dev/kmem" , NULL, O_RDONLY, NULL)))
X {
X if (syslog_flag) syslog(LOG_ERR, "kvm_open call failed");
X return 1;
X }
X
X if (kvm_nlist(kd, name_list) != 0)
X {
X if (syslog_flag) syslog(LOG_ERR, "kvm_nlist call failed");
X return 1;
X }
X
X return 0;
}
X
X
int k_getuid(struct in_addr *faddr, int fport,
X struct in_addr *laddr, int lport,
X int *uid
#ifdef ALLOW_FORMAT
X , int *pid
X , char **cmd
X , char **cmd_and_args
#endif
X )
{
X off_t pidtab_base; /* Start address of the process table */
X int npid; /* Number of processes in the process table */
X
X struct proc_plus_utask {
X struct proc The_Proc;
X struct utask Proc_Utask;
X } pu;
X
X struct pid_entry *the_pid_entry;
X struct file **ofile_table_extension, open_file;
X int index, index1;
X
#define the_proc pu.The_Proc
#define proc_utask pu.Proc_Utask
#define p_i the_pid_entry[index]
#define f_s proc_utask.uu_file_state
X
X static char zapmess[BUFLEN];
X long zaplevel;
X
#ifdef ALLOW_FORMAT
X static char cmdbuf[BUFLEN];
X static char c_abuf[BUFLEN];
X int blen;
#endif
X
X
/* Just to save us some typing: we ALWAYS test return from kvm_read */
#define goodr(k,addr,buf,len) (kvm_read(k,addr,buf,len) == len)
#define badr(k,addr,buf,len) (kvm_read(k,addr,buf,len) != len)
X
X
#ifdef OFILE_EXTEND
X /* Reserve space for the extended open file table of a process */
X ofile_table_extension = (struct file **) alloca((getdtablesize ())
X * sizeof(struct file *));
#endif
X
X
X /* Do we need these extra checks? */
X ZAP(fport<1 || fport>65535 || lport<1 || lport>65535, "port numbers out of range",0)
X ZAP(faddr->s_addr==0 || faddr->s_addr==-1 || laddr->s_addr==0 || laddr->s_addr==-1, "net addresses out of range",0)
X
#ifdef DEBUG
X printf ("Looking up faddr %08x fport %d\n", faddr->s_addr, fport);
X printf (" laddr %08x lport %d\n", laddr->s_addr, lport);
#endif /* DEBUG */
X
X
X zaplevel = 0;
X sprintf (zapmess, "no such TCP connection");
X
X
X /* Find the start of the process table */
X ZAP(badr(kd, (off_t) name_list[N_PIDTAB].n_value, &pidtab_base, sizeof(pidtab_base)),
X "Cannot read pidtab_base",0)
X
X /* Find the size of the process table */
X ZAP(badr(kd, (off_t) name_list[N_NPID].n_value, &npid, sizeof(npid)), "Cannot read npid",0)
X /* Sanity check */
X ZAP(npid < 1 || npid > 20000, "Bad npid of %d", npid)
X
/*
** To improve on the 20000 above:
**
** (method 1)
**
** We observe that npid is 1024 or 4096.
** (Are any other multiples of 1024 allowed?)
** Accept these allowed values only.
**
** (method 2) THIS WOULD NOT WORK:
**
** Change the declaration of name_list at the beginning to:
**
** struct nlist name_list[] = {
** #define N_PIDTAB 0
** { "_pidtab" },
** #define N_NPID 1
** { "_npid" },
** #define N_TASKMAX 2
** { "task_max" },
** { 0 }
** };
**
** then use
**
** int taskmax;
** kvm_read (kd, (off_t) name_list[N_TASKMAX].n_value, &taskmax, sizeof(taskmax));
**
** and then replace 20000 by taskmax-1.
**
** But then, we are still relying on values returned from kvm_read...
** or put another way, we have no good way of checking taskmax.
**
** This probably would not work anyway: our DEC 2100 should show around
** 1000 for taskmax (128 users), but npid returned is 4096.
*/
X
#ifdef DEBUG
X printf ("Number of processes: %d\n", npid);
#endif /* DEBUG */
X
X
X /* Read in the process structure */
X the_pid_entry = (struct pid_entry*)alloca(sizeof(struct pid_entry) * npid);
X ZAP(badr(kd, pidtab_base, the_pid_entry, sizeof(struct pid_entry) * npid),
X "Cannot read process structure",0)
X
X for (index = 0; index < npid; index++) {
X
X /* Sanity checks */
X /*
X This is a 'normal' thing:
X SETZAP(p_i.pe_proc == 0, 11, "Proc/utask pointer zero for proc slot %d",index,0,0)
X */
X if (p_i.pe_proc == 0) continue;
X SETZAP(PID_INVALID(p_i.pe_pid), 12, "Invalid PID %d for proc slot %d",p_i.pe_pid,index,0)
X
X /* Read in the proc and utask structs of the process */
X SETZAP(badr(kd, (off_t) p_i.pe_proc, &pu, sizeof(pu)), 13,
X "Cannot read proc/utask for proc slot %d (PID %d)",index,p_i.pe_pid,0)
X
X /* Sanity checks */
X SETZAP(p_i.pe_pid != the_proc.p_pid, 21,
X "Proc slot %d was PID %d, but has %d in proc/utask",index,p_i.pe_pid,the_proc.p_pid)
X SETZAP(INVALID_UID(the_proc.p_ruid), 22,
X "Invalid UID %d for proc slot %d (PID %d)",the_proc.p_ruid,index,p_i.pe_pid)
X
#ifdef DEBUG
X printf ("Looking at proc slot %d: PID %d, UID %d\n", index, the_proc.p_pid, the_proc.p_ruid);
#endif /* DEBUG */
X
X /* Sanity checks */
X if (f_s.uf_lastfile < 0) continue;
X SETZAP((f_s.uf_lastfile + 1) > getdtablesize(), 31,
X "Too many files used (%d) for proc slot %d (PID %d)",f_s.uf_lastfile,index,p_i.pe_pid)
X
#ifdef OFILE_EXTEND
X if (f_s.uf_lastfile >= NOFILE_IN_U) {
X /* Sanity checks */
X SETZAP(f_s.uf_of_count > (getdtablesize()), 32,
X "Too many (%d) OFILE_EXTEND files used for proc slot %d (PID %d)",f_s.uf_of_count,index,p_i.pe_pid)
X
#if 0 /* Disabled, 960811 Peter Eriksson <p...@lysator.liu.se< */
X SETZAP((f_s.uf_lastfile + 1) != (f_s.uf_of_count + NOFILE_IN_U), 33,
X "Files used %d, but %d OFILE_EXTEND ones for proc slot %d",f_s.uf_lastfile,f_s.uf_of_count,index)
#endif
X
X SETZAP(badr(kd, (off_t) f_s.uf_ofile_of, ofile_table_extension, f_s.uf_of_count * sizeof(struct file *)), 34,
X "Cannot read OFILE_EXTEND files for proc slot %d (PID %d)",index,p_i.pe_pid,0)
X }
#endif
X
#ifdef DEBUG
X printf ("proc slot %d uses %d files\n", index, f_s.uf_lastfile);
#endif /* DEBUG */
X
X for (index1 = 0; index1 <= f_s.uf_lastfile; index1++) {
X
X if (index1 < NOFILE_IN_U) {
X if (f_s.uf_ofile[index1] == (struct file *) NULL) continue;
X if (f_s.uf_ofile[index1] == (struct file *) -1) continue;
X
X SETZAP(badr(kd, (off_t) f_s.uf_ofile[index1], &open_file, sizeof(open_file)), 41,
X "Cannot read file %d for proc slot %d (PID %d)",index1,index,p_i.pe_pid)
X }
#ifdef OFILE_EXTEND
X else {
X if (ofile_table_extension[index1-NOFILE_IN_U] == (struct file *) NULL) continue;
X
X SETZAP(badr(kd,(off_t) ofile_table_extension[index1-NOFILE_IN_U], &open_file, sizeof(open_file)), 42,
X "Cannot read OFILE_EXTEND file %d for proc slot %d (PID %d)",index1,index,p_i.pe_pid)
X }
#endif
X
#ifdef DEBUG
X printf ("Looking at proc slot %d, file %d\n", index, index1);
#endif /* DEBUG */
X
X if (open_file.f_type == DTYPE_SOCKET) {
X
X struct socket try_socket;
X struct inpcb try_pcb;
X
X SETZAP(badr(kd,(off_t) open_file.f_data, &try_socket,sizeof(try_socket)), 51,
X "Cannot read socket of file %d for proc slot %d (PID %d)",index1,index,p_i.pe_pid)
X if (try_socket.so_pcb) {
X SETZAP(badr(kd, (off_t) try_socket.so_pcb, &try_pcb,sizeof(try_pcb)), 52,
X "Cannot read pcb of file %d for proc slot %d (PID %d)",index1,index,p_i.pe_pid)
X if (try_pcb.inp_faddr.s_addr == faddr->s_addr &&
X try_pcb.inp_laddr.s_addr == laddr->s_addr &&
X try_pcb.inp_fport == fport &&
X try_pcb.inp_lport == lport ) {
X
X *uid = the_proc.p_ruid;
X
#ifdef ALLOW_FORMAT
X
X *pid = the_proc.p_pid;
X
X blen = strlen(proc_utask.uu_comm);
X if (blen > BUFLEN-1) blen = BUFLEN-1;
X sprintf(cmdbuf, "%.*s", blen, proc_utask.uu_comm);
X *cmd = cmdbuf;
X
/*
How to use proc_utask.uu_arg_size and proc_utask.uu_argp ??
The value proc_utask.uu_arg_size seems to be the length of the
cmd+args string (including trailing null), but where is the string?
X
Neither of the following two ways work:
Way 1:
X blen = strlen(proc_utask.uu_argp);
X if (blen > BUFLEN-1) blen = BUFLEN-1;
X sprintf(c_abuf, "%.*s", blen, proc_utask.uu_argp);
X
Way 2:
X blen = proc_utask.uu_arg_size;
X if (blen > BUFLEN-1) blen = BUFLEN-1;
X SETZAP(badr(kd, (off_t) proc_utask.uu_argp,c_abuf,blen), 53, "Cannot read cmd args for proc slot %d (PID %d)",index,p_i.pe_pid,0)
X c_abuf[blen] = 0;
X
Finally:
X *cmd_and_args = c_abuf;
*/
X
/*
** Other stuff we could return:
** login_namep = proc_utask.uu_logname;
** envp = proc_utask.uu_envp;
** n_env = proc_utask.uu_env_size;
*/
X
#endif
X
X return (0);
X };
X };
X continue; /* Is not this superfluous? We are at the end of the file loop anyway. */
X };
X };
X };
X ZAP(1,zapmess,0)
X return (-1);
}
SHAR_EOF
$shar_touch -am 0811205196 'pidentd-2.7/src/kernel/alpha3.c' &&
chmod 0644 'pidentd-2.7/src/kernel/alpha3.c' ||
$echo 'restore of' 'pidentd-2.7/src/kernel/alpha3.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/kernel/alpha3.c:' 'MD5 check failed'
ff2a623afc172448cf7747f953a413c6 pidentd-2.7/src/kernel/alpha3.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/alpha3.c'`"
test 13380 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/kernel/alpha3.c:' 'original size' '13380,' 'current size' "$shar_count!"
fi
fi
# ============= pidentd-2.7/src/kernel/netbsd.c ==============
if test -f 'pidentd-2.7/src/kernel/netbsd.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/netbsd.c' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/kernel/netbsd.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/netbsd.c' &&
/*
** $Id: netbsd.c,v 1.8 1995/07/08 23:57:06 pk Exp $
**
** netbsd.c Low level kernel access functions for NetBSD
**
** This program is in the public domain and may be used freely by anyone
** who wants to.
**
** Last update: 17 March 1993
**
** Please send bug fixes/bug reports to: Peter Eriksson <p...@lysator.liu.se>
*/
X
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <nlist.h>
#include <pwd.h>
#include <signal.h>
#include <syslog.h>
X
#include "kvm.h"
X
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
X
#include <sys/socketvar.h>
X
#define _KERNEL
X
#include <sys/file.h>
X
#undef _KERNEL
#include <sys/sysctl.h>
X
#include <fcntl.h>
X
#include <sys/user.h>
X
#include <sys/wait.h>
X
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
X
#include <netinet/in_systm.h>
#include <netinet/ip.h>
X
#include <netinet/in_pcb.h>
X
#include <netinet/tcp.h>
#include <netinet/ip_var.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
X
#include <arpa/inet.h>
X
#include "identd.h"
#include "error.h"
X
X
extern void *calloc();
extern void *malloc();
X
X
struct nlist nl[] =
{
#define N_FILE 0
#define N_NFILE 1
#define N_TCBTABLE 2
X
X { "_filehead" },
X { "_nfiles" },
X { "_tcbtable" },
X { "" }
};
X
static kvm_t *kd;
X
static struct file *xfile;
static int nfile;
X
static struct inpcbtable tcbtable;
X
X
int k_open()
{
X char errbuf[_POSIX2_LINE_MAX];
X
X /*
X ** Open the kernel memory device
X */
X if ((kd = kvm_openfiles(path_unix, path_kmem, NULL, O_RDONLY, errbuf)) ==
X NULL)
X ERROR1("main: kvm_open: %s", errbuf);
X
X /*
X ** Extract offsets to the needed variables in the kernel
X */
X if (kvm_nlist(kd, nl) < 0)
X ERROR("main: kvm_nlist");
X
X return 0;
}
X
X
/*
** Get a piece of kernel memory with error handling.
** Returns 1 if call succeeded, else 0 (zero).
*/
static int getbuf(addr, buf, len, what)
X long addr;
X char *buf;
X int len;
X char *what;
{
X if (kvm_read(kd, addr, buf, len) < 0)
X {
X if (syslog_flag)
X syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
X addr, len, what);
X
X return 0;
X }
X
X return 1;
}
X
X
X
/*
** Traverse the inpcb list until a match is found.
** Returns NULL if no match.
*/
static struct socket *
getlist(tcbtablep, ktcbtablep, faddr, fport, laddr, lport)
X struct inpcbtable *tcbtablep, *ktcbtablep;
X struct in_addr *faddr;
X int fport;
X struct in_addr *laddr;
X int lport;
{
X struct inpcb *kpcbp, pcb;
X
X if (!tcbtablep)
X return NULL;
X
X for (kpcbp = tcbtablep->inpt_queue.cqh_first;
X kpcbp != (struct inpcb *)ktcbtablep;
X kpcbp = pcb.inp_queue.cqe_next) {
X if (!getbuf((long) kpcbp, &pcb, sizeof(struct inpcb), "tcb"))
X break;
X if (pcb.inp_faddr.s_addr == faddr->s_addr &&
X pcb.inp_laddr.s_addr == laddr->s_addr &&
X pcb.inp_fport == fport &&
X pcb.inp_lport == lport )
X return pcb.inp_socket;
X }
X return NULL;
}
X
X
X
/*
** Return the user number for the connection owner
*/
int k_getuid(faddr, fport, laddr, lport, uid)
X struct in_addr *faddr;
X int fport;
X struct in_addr *laddr;
X int lport;
X int *uid;
{
X long addr;
X struct socket *sockp;
X int i, mib[2];
X struct ucred ucb;
X
X /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
X if (!getbuf(nl[N_NFILE].n_value, &nfile, sizeof(nfile), "nfile"))
X return -1;
X
X if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
X return -1;
X
X {
X size_t siz;
X int rv;
X
X mib[0] = CTL_KERN;
X mib[1] = KERN_FILE;
X if ((rv = sysctl(mib, 2, NULL, &siz, NULL, 0)) == -1)
X {
X ERROR1("k_getuid: sysctl 1 (%d)", rv);
X return -1;
X }
X xfile = malloc(siz);
X if (!xfile)
X ERROR1("k_getuid: malloc(%d)", siz);
X if ((rv = sysctl(mib, 2, xfile, &siz, NULL, 0)) == -1)
X {
X ERROR1("k_getuid: sysctl 2 (%d)", rv);
X return -1;
X }
X xfile = (struct file *)((char *)xfile + sizeof(filehead));
X }
X
X /* -------------------- TCP PCB LIST -------------------- */
X if (!getbuf(nl[N_TCBTABLE].n_value, &tcbtable, sizeof(tcbtable), "tcbtable"))
X return -1;
X
X sockp = getlist(&tcbtable, nl[N_TCBTABLE].n_value, faddr, fport, laddr,
X lport);
X
X if (!sockp)
X return -1;
X
X /*
X ** Locate the file descriptor that has the socket in question
X ** open so that we can get the 'ucred' information
X */
X for (i = 0; i < nfile; i++)
X {
X if (xfile[i].f_count == 0)
X continue;
X
X if (xfile[i].f_type == DTYPE_SOCKET &&
X (struct socket *) xfile[i].f_data == sockp)
X {
X if (!getbuf(xfile[i].f_cred, &ucb, sizeof(ucb), "ucb"))
X return -1;
X
X *uid = ucb.cr_uid;
X return 0;
X }
X }
X
X return -1;
}
X
SHAR_EOF
$shar_touch -am 0811224796 'pidentd-2.7/src/kernel/netbsd.c' &&
chmod 0644 'pidentd-2.7/src/kernel/netbsd.c' ||
$echo 'restore of' 'pidentd-2.7/src/kernel/netbsd.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/kernel/netbsd.c:' 'MD5 check failed'
1bd2597c14e706f1ce16ae7ebb8c286e pidentd-2.7/src/kernel/netbsd.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/netbsd.c'`"
test 4698 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/kernel/netbsd.c:' 'original size' '4698,' 'current size' "$shar_count!"
fi
fi
# ============= pidentd-2.7/src/kernel/apollo.c ==============
if test -f 'pidentd-2.7/src/kernel/apollo.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/apollo.c' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/kernel/apollo.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/apollo.c' &&
/*
X * 12 Apr 96 - Written by Paul Szabo <p...@maths.usyd.edu.au>
X */
X
#include <stdio.h>
#include <ctype.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include <signal.h>
#include <setjmp.h>
#include <apollo/base.h>
#include <apollo/name.h> /* Not really needed */
#include <apollo/pgm.h>
X
#include "identd.h"
#include "error.h"
X
X
#define USE_SAFE_ADDR
X
X
#define BUFLEN 256 /* buffer length, 80 would probably be enough */
X
X
/* These are from #include <limits.h>, but is only with #ifdef _INCLUDE_SYS5_SOURCE */
#define PID_MAX 30000 /* max value for a process ID */
#define UID_MAX 65535 /* max value for a user or group ID */
X
typedef unsigned int tcp_$netaddr_t;
/* An address of 129.78.69.2 is 0x814e4502 as int,
X or [0] is 0x81, [1] is 0x4e, [2] is 0x45, [3] is 0x02 as char array */
X
typedef struct { /* network status structure */
/* Note the mismatches between /sys/ins/tcp.ins.{pas,c}, both dated 3 May 89 */
X unsigned short nsnd; /* # send bufs allocated */ /* Always 0x239c */
X unsigned short nrcv; /* # receive bufs allocated */ /* Either 0x239c, or maybe 0x2000, 0x8000 or 0xc000 */
X unsigned short ssize; /* # bufs on send buffer */ /* Stuff in queue, sndQ */
X unsigned short rsize; /* # bufs on receive buffer */ /* Stuff in queue, rcvQ */
X unsigned short xstat; /* network status word */
X unsigned short state; /* state of this connection */
X unsigned short iostate;
X unsigned short flags; /* misc. flags (see below) */ /* See where??? 0x0002 tcp, 0x0220 udp, 0x0804 ip */
X unsigned short lport; /* local port */
X unsigned short rport; /* foreign port */
X tcp_$netaddr_t raddr; /* foreign address */
X tcp_$netaddr_t laddr; /* local address */
X unsigned short options; /* corresponds to ucb uc_options */
X unsigned short pad1; /* Padding for alignment */
} tcp_$netstate_t;
X
typedef char enum {
X tcp_$CLOSED,
X tcp_$LISTEN,
X tcp_$SYN_SENT,
X tcp_$state_0x03,
X tcp_$state_0x04,
X tcp_$ESTABLISHED,
X tcp_$state_0x06,
X tcp_$state_0x07,
X tcp_$TIME_WAIT,
X tcp_$CLOSE_WAIT,
X tcp_$state_0x0a,
X tcp_$CLOSING
} tcp_$tcpstate_t;
X
typedef struct { /* Complete state of a connection */
/*
X * Both /sys/ins/tcp.ins.{pas,c} have 8-character ifname (so mis-alignment at ifunit);
X * /sys/ins/tcp.ins.pas has process UID instead of pgrp.
X */
X tcp_$netstate_t cstate;
X tcp_$netaddr_t route; /* Gateway address, if any */
X char *tcb; /* The tcb, if any, for this connection */
X tcp_$tcpstate_t tstate; /* State of tcp connection, if any */
X char ifname[9]; /* Name of network interface */
X pinteger ifunit; /* Unit number of device */
X pinteger pr_num; /* Raw protocol number, if any */
X uid_$t pgrp #attribute[aligned(1)]; /* Process group (??) */
} tcp_$constate_t;
X
typedef tcp_$constate_t *tcp_$constate_p;
X
typedef short enum {
X tcp_$memstats,
X tcp_$netstats,
X tcp_$ifcbs,
X tcp_$tcbs,
X tcp_$hosts,
X tcp_$gateway,
X tcp_$all_conns
} tcp_$info_key_t;
X
#define MAXCON 0x0080 /* Why 128??? This is what netstat uses.
X What happens if there are more connections? */
X
void extern tcp_$get_server_info (
X tcp_$info_key_t &key,
X tcp_$constate_p &state_p,
X short &statesize,
X short &max_con,
X short *num_con,
X status_$t *status);
X
X
typedef struct {
X uid_$t pers;
X uid_$t proj;
X uid_$t org ;
X uid_$t subs;
X long node;
X } acl_$sid;
X
X
#define proc2_$aname_len 32
typedef char proc2_$aname_t[proc2_$aname_len]; /* accounting name */
X
typedef short proc2_$state_t;
typedef struct {
X uid_$t stack_uid; /* uid of user stack */
X linteger stack_base; /* base address of user stack */
X proc2_$state_t state; /* ready, waiting, etc. */
X pinteger usr; /* user sr */
X linteger upc; /* user pc */
X linteger usp; /* user stack pointer */
X linteger usb; /* user sb ptr (A6) */
X time_$clock_t cpu_total; /* cumulative cpu used by process */
X pinteger priority; /* process priority */
X acl_$sid sid; /* sid of process */
X uid_$t pgroup; /* process group uid */
X boolean is_server; /* process is a server */
X boolean pad;
X pinteger min_pri; /* min priority of process (1..16) */
X pinteger max_pri; /* max priority of process (1..16) */
X linteger exec_faults; /* execute faults */
X linteger data_faults; /* data faults */
X linteger disk_pageIO; /* disk paging */
X linteger net_pageIO; /* net paging */
X uid_$t orig_pgroup; /* original process group */
X pinteger orig_upgid; /* original unix process group */
X pinteger unix_PID; /* Unix process ID */
X pinteger unix_PPID; /* Unix Process Parent ID */
X pinteger unix_PGID; /* Unix Process Group ID */
X pinteger udpid; /* unix debugger id */
X pinteger asid; /* address space id */
X uid_$t acct_uid; /* uid of command being run */
X pinteger acct_len; /* length of command name */
X proc2_$aname_t acct_name; /* name of the invoked command */
X pinteger proc_len; /* length of process name */
X proc2_$aname_t proc_name; /* process name */
X uid_$t tty_uid; /* uid of controlling terminal */
X pinteger pad2;
X time_$clock_t cpu_time; /* total CPU time used */
X pinteger pad3;
X linteger user_ticks; /* ticks executing in user space */
X linteger system_ticks; /* ticks executing in system space */
X linteger tick_size; /* size of a tick in microseconds */
} proc2_$info_t;
X
extern void proc2_$upid_to_uid (
X short &upid, /* convert unix pid to puid */
X uid_$t *p2_uid,
X status_$t *status
X );
X
extern void proc2_$get_info(
X uid_$t &p2_uid,
X proc2_$info_t *info,
X pinteger &info_buf_len, /* size of info buffer (bytes) */
X status_$t *status
X );
X
X
/*
X * Converts SID to string: <person.group.org.nodeID> or maybe
X * <person.group.org.nodeID.subsys>. Writes the string
X * without adding a null byte: zero the buffer first.
X */
extern void rgyc_$sid2text (
X acl_$sid &sid,
X char *buffer,
X status_$t *status
X );
X
/* Surely we could use rgyc_$pgo_uid_to_name instead */
X
typedef int acl_$unix_id;
X
/*
X * Converts UID to UNIX number, for pers, proj or org.
X */
extern void rgyc_$pgo_uid_to_num (
X int &domain, /* convert: 0: pers, 1: proj, 2: org */
X uid_$t &uid, /* UID to convert */
X short *unknown, /* set to 0 for pers or proj, 0 for org (why??) */
X acl_$unix_id *num, /* UNIX number */
X status_$t *status);
X
X
typedef short enum { /* Returned by VALIDATE */
X name_$junk_flag,
X name_$wdir_flag,
X name_$ndir_flag,
X name_$node_flag,
X name_$root_flag,
X name_$node_data_flag,
X name_$cs_flag
} name_$namtyp_t;
X
/*
X * Do a gpath on an object UID
X */
extern void name_$gpath_lc (
X uid_$t &inuid,
X name_$namtyp_t &namtyp,
X pinteger &maxpnamlen,
X name_$long_pname_t pname,
X pinteger *pnamlen,
X status_$t *status);
X
X
extern void context_$set (
X uid_$t &p2_uid,
X status_$t *status);
X
extern void pgm_$context_get_args (
X short *argument_count,
X pgm_$argv_ptr *arg_vector_ptr,
X status_$t *status);
X
/* Look up values in other process's address space */
extern void xpd_$locate_proc (
X uid_$t &p2_uid,
X void &address,
X int zero[2], /* Is this some UID? Why need to set to zero? */
X void *value,
X int *stat, /* Why does always get set to 0x070000 ? Is it really a short? */
X status_$t *status);
X
X
#ifdef USE_SAFE_ADDR
static jmp_buf jmpenv;
X
void my_fault_handler (int sig)
{
X _longjmp (jmpenv, 1);
X exit (1); /* This should never be reached */
}
X
/*
X * Tests if object at addr, of length len, is readable.
X * Any way to do this easier??? Must I generate and trap an error???
X * Does not test each address, only endpoints of range.
X */
int testaddr (char addr[], long len)
{
X char c1, c2;
X
X if (_setjmp (jmpenv)) {
X signal (11, SIG_DFL);
X return (0);
X }
X
X c1 = 0; c2 = 0;
X signal (11, my_fault_handler);
X c1 = addr[0];
X if (len > 0 && len < 100000) c2 = addr[len];
X signal (11, SIG_DFL);
X
X /*
X * While all we want is to look up c1,c2, we must actually use them,
X * otherwise the optimiser may eliminate the assignments.
X */
X return (((int)(c1|c2)&0x00ff) + 1024);
}
#endif /* USE_SAFE_ADDR */
X
X
#ifdef DEBUG
#define sysl(a,b) printf(a, b); printf("\n");
#else /* DEBUG */
#ifdef STRONG_LOG
X /* This isn't worth the time for the procedure call, but if you want... */
#define sysl(a,b) if (syslog_flag) { syslog(LOG_INFO, a, b); }
#else
#define sysl(a,b)
#endif
#endif /* DEBUG */
X
X
#define ZAP(x,fmt,err) \
X if (x) \
X { \
X sysl(fmt, err) \
X return (-1); \
X }
X
#ifdef DEBUG
#define SETZAP(x,lev,fmt,err1,err2,err3) \
X if (x) \
X { \
X printf ("zap to level %d: ", lev); printf (fmt, err1, err2, err3); printf ("\n"); \
X if (lev > zaplevel) \
X { \
X sprintf (zapmess, fmt, err1, err2, err3); \
X zaplevel = lev; \
X printf ("zap level set to %d\n", zaplevel); \
X } \
X continue; \
X }
#else /* DEBUG */
#define SETZAP(x,lev,fmt,err1,err2,err3) \
X if (x) \
X { \
X if (lev > zaplevel && syslog_flag) \
X { \
X sprintf (zapmess, fmt, err1, err2, err3); \
X zaplevel = lev; \
X } \
X continue; \
X }
#endif /* DEBUG */
X
X
struct UCB;
struct PCB;
X
struct PCB
{
X struct PCB *self1;
X struct PCB *self2;
X struct PCB *next;
X struct PCB *prev;
X struct UCB *ucb;
} *sock_PCB;
X
struct UCB
{
X struct UCB *next;
X struct UCB *prev;
X struct in_addr ucb_faddr;
X struct in_addr ucb_laddr;
X u_short ucb_fport;
X u_short ucb_lport;
X struct PCB *pcb;
X void *Unknown; /* What is this for??? */
X char Dummy[PIDOFF]; /* What goodies lurk within??? */
X short PID;
} *sock_UCB;
X
/*
Known good values of PIDOFF:
X OS Version PIDOFF
X 10.2 m68k 0x46 (probably should be higher!)
X 10.3 m68k 0xc9
X 10.4 m68k 0xc9
X 10.4.1 m68k 0xc9
X 10.4.1 a88k 0x52 (probably should be higher!)
Some values should be higher to correctly allow for incoming
telnet connections (and find the running shell, not a PID of
zero or the PID of telnetd).
*/
X
X
X
int k_open()
{
X /* Apollos do not use this rubbish */
X return 0;
}
X
X
X
int k_getuid(struct in_addr *faddr, int fport,
X struct in_addr *laddr, int lport,
X int *uid
#ifdef ALLOW_FORMAT
X , int *retpid
X , char **retcmd
X , char **retcmd_and_args
#endif
X )
{
X int pcb, ucb;
X short pid;
X
X status_$t status;
X
X tcp_$netaddr_t tcp_ra, tcp_la;
X unsigned short tcp_rp, tcp_lp;
X tcp_$constate_t tcp_state[MAXCON];
X short tcp_ncon;
X long tcp_i;
X
X uid_$t p2_uid;
X proc2_$info_t p2_info;
X
X int domain;
X acl_$unix_id unix_num;
X short unknown;
X
#ifdef ALLOW_FORMAT
X static name_$long_pname_t pname;
X pinteger pnamlen;
X
X short arg_count;
X pgm_$arg *arg;
X pgm_$arg_ptr *arg_ptr, *arg_ptr2;
X pgm_$argv_ptr arg_vector_ptr;
X
X static name_$long_pname_t cmdarg;
#endif
X
X static char zapmess[BUFLEN];
X long zaplevel;
X
X
X /* Do we need this extra check? */
X ZAP(fport<1 || fport>65535 || lport<1 || lport>65535, "port numbers out of range",0)
X tcp_rp = fport & 0xffff;
X tcp_lp = lport & 0xffff;
X
X /* Do we need this extra check? */
X ZAP(faddr->s_addr==0 || faddr->s_addr==-1 || laddr->s_addr==0 || laddr->s_addr==-1, "net addresses out of range",0)
X tcp_ra = faddr->s_addr;
X tcp_la = laddr->s_addr;
X
X zaplevel = 0;
X sprintf (zapmess, "no such TCP connection");
X
X
X tcp_$get_server_info (
X tcp_$all_conns,
X tcp_state,
X (short) sizeof(tcp_$constate_t),
X MAXCON,
X &tcp_ncon,
X &status);
X ZAP (status.all,"tcp_$get_server_info failed with status %08x",status.all)
X
X for (tcp_i=0; tcp_i<tcp_ncon; tcp_i++) {
#ifdef DEBUG
X printf ("\n");
X printf ("Connection %d (of %d):\n", tcp_i, tcp_ncon);
X printf ("cstate.nsnd %6d (%04x)\n", tcp_state[tcp_i].cstate.nsnd&0xffff, tcp_state[tcp_i].cstate.nsnd&0xffff);
X printf ("cstate.nrcv %6d (%04x)\n", tcp_state[tcp_i].cstate.nrcv&0xffff, tcp_state[tcp_i].cstate.nrcv&0xffff);
X printf ("cstate.ssize %6d (%04x)\n", tcp_state[tcp_i].cstate.ssize&0xffff, tcp_state[tcp_i].cstate.ssize&0xffff);
X printf ("cstate.rsize %6d (%04x)\n", tcp_state[tcp_i].cstate.rsize&0xffff, tcp_state[tcp_i].cstate.rsize&0xffff);
X printf ("cstate.xstat %6d (%04x)\n", tcp_state[tcp_i].cstate.xstat&0xffff, tcp_state[tcp_i].cstate.xstat&0xffff);
X printf ("cstate.state %6d (%04x)\n", tcp_state[tcp_i].cstate.state&0xffff, tcp_state[tcp_i].cstate.state&0xffff);
X printf ("cstate.iostate %6d (%04x)\n", tcp_state[tcp_i].cstate.iostate&0xffff, tcp_state[tcp_i].cstate.iostate&0xffff);
X printf ("cstate.flags %6d (%04x)\n", tcp_state[tcp_i].cstate.flags&0xffff, tcp_state[tcp_i].cstate.flags&0xffff);
X printf ("cstate.lport %6d (%04x)\n", tcp_state[tcp_i].cstate.lport&0xffff, tcp_state[tcp_i].cstate.lport&0xffff);
X printf ("cstate.rport %6d (%04x)\n", tcp_state[tcp_i].cstate.rport&0xffff, tcp_state[tcp_i].cstate.rport&0xffff);
X printf ("cstate.raddr %08x\n", tcp_state[tcp_i].cstate.raddr);
X printf ("cstate.laddr %08x\n", tcp_state[tcp_i].cstate.laddr);
X printf ("cstate.options %6d (%04x)\n", tcp_state[tcp_i].cstate.options&0xffff, tcp_state[tcp_i].cstate.options&0xffff);
X printf ("cstate.pad1 %6d (%04x)\n", tcp_state[tcp_i].cstate.pad1&0xffff, tcp_state[tcp_i].cstate.pad1&0xffff);
X printf ("route %08x\n", tcp_state[tcp_i].route);
X printf ("tcb %08x\n", (int)tcp_state[tcp_i].tcb);
X printf ("tstate %02x\n", tcp_state[tcp_i].tstate&0xff);
X printf ("ifname %.9s\n", tcp_state[tcp_i].ifname);
X printf ("ifunit %6d (%04x)\n", tcp_state[tcp_i].ifunit&0xffff, tcp_state[tcp_i].ifunit&0xffff);
X printf ("pr_num %6d (%04x)\n", tcp_state[tcp_i].pr_num&0xffff, tcp_state[tcp_i].pr_num&0xffff);
X printf ("pgrp %08x.%08x\n", tcp_state[tcp_i].pgrp.high, tcp_state[tcp_i].pgrp.low);
X printf ("\n");
#endif /* DEBUG */
X
X
X if (
X (tcp_state[tcp_i].cstate.raddr == tcp_ra &&
X tcp_state[tcp_i].cstate.laddr == tcp_la &&
X tcp_state[tcp_i].cstate.rport == tcp_rp &&
X tcp_state[tcp_i].cstate.lport == tcp_lp)) {
X /* What??? No sanity check of tcp_state[tcp_i].tstate ? */
X
X pcb = (int)tcp_state[tcp_i].tcb;
X
X /* We must not just ZAP on error, but keep message and loop through all lines/connections */
X
X SETZAP(!pcb, 11, "pcb is zero (closed?)",0,0,0)
#ifdef USE_SAFE_ADDR
X SETZAP(!testaddr((char*)pcb,sizeof(*sock_PCB)), 12, "pcb at %08x is unreadable",pcb,0,0)
#endif /* USE_SAFE_ADDR */
X sock_PCB = (struct PCB *) pcb;
X
#ifdef DEBUG
X printf ("PCB.self1 %08x\n", (int)sock_PCB->self1);
X printf ("PCB.self2 %08x\n", (int)sock_PCB->self2);
X printf ("PCB.next %08x\n", (int)sock_PCB->next);
X printf ("PCB.prev %08x\n", (int)sock_PCB->prev);
X printf ("PCB.ucb %08x\n", (int)sock_PCB->ucb);
X printf ("\n");
#endif /* DEBUG */
X
X SETZAP(pcb!=(int)sock_PCB->self1, 13, "pcb at %d, but PCB.self1 at %d",pcb,(int)sock_PCB->self1,0)
X SETZAP(pcb!=(int)sock_PCB->self2, 14, "pcb at %d, but PCB.self2 at %d",pcb,(int)sock_PCB->self2,0)
X
X ucb = (int)sock_PCB->ucb;
X /* Cannot just test ucb==0: usually we get bogus, but non-null, ucb addresses. */
#ifdef USE_SAFE_ADDR
X SETZAP(!(ucb&0xffff0000), 21, "ucb is zero (closed?)",0,0,0)
X SETZAP(!testaddr((char*)ucb,sizeof(*sock_UCB)), 22, "ucb at %08x is unreadable",ucb,0,0)
#else /* USE_SAFE_ADDR */
X SETZAP(!(ucb&0xf0000000), 21, "ucb is zero (closed?)",0,0,0)
#endif /* USE_SAFE_ADDR */
X sock_UCB = (struct UCB *) ucb;
X
#ifdef DEBUG
X printf ("UCB.next %08x\n", (int)sock_UCB->next);
X printf ("UCB.prev %08x\n", (int)sock_UCB->prev);
X printf ("UCB.ucb_faddr %08x\n", (int)sock_UCB->ucb_faddr.s_addr);
X printf ("UCB.ucb_laddr %08x\n", (int)sock_UCB->ucb_laddr.s_addr);
X printf ("UCB.ucb_fport %6d (%04x)\n", sock_UCB->ucb_fport&0xffff, sock_UCB->ucb_fport&0xffff);
X printf ("UCB.ucb_lport %6d (%04x)\n", sock_UCB->ucb_lport&0xffff, sock_UCB->ucb_lport&0xffff);
X printf ("UCB.pcb %08x\n", (int)sock_UCB->pcb);
X printf ("UCB.Unknown %08x\n", (int)sock_UCB->Unknown);
X printf ("UCB.PID %6d (%04x)\n", sock_UCB->PID&0xffff, sock_UCB->PID&0xffff);
X printf ("\n");
X {
X long i;
X char *cp;
X short *sp;
X long *lp, *qp;
X
X printf ("The Dummy array:\n");
X printf (" index byte short long quad\n");
X for (cp=sock_UCB->Dummy, i=0; i<256; i++, cp++) {
X sp = (short *) cp;
X lp = (long *) cp;
X qp = (long *) (cp + 4);
X printf ("%6d %04x %6d %02x %8d %04x %13d %08x %08x.%08x\n", i,i,*cp,*cp&0xff,*sp,*sp&0xffff,*lp,*lp,*lp,*qp);
X }
X }
X printf ("\n");
#endif /* DEBUG */
X
X SETZAP(tcp_ra!=(int)sock_UCB->ucb_faddr.s_addr, 23, "Wanted faddr %08x, but found %08x",tcp_ra,(int)sock_UCB->ucb_faddr.s_addr,0)
X SETZAP(tcp_la!=(int)sock_UCB->ucb_laddr.s_addr, 24, "Wanted laddr %08x, but found %08x",tcp_la,(int)sock_UCB->ucb_laddr.s_addr,0)
X SETZAP(tcp_rp!=sock_UCB->ucb_fport, 25, "Wanted fport %d, but found %d",tcp_rp,sock_UCB->ucb_fport,0)
X SETZAP(tcp_lp!=sock_UCB->ucb_lport, 26, "Wanted lport %d, but found %d",tcp_lp,sock_UCB->ucb_lport,0)
X SETZAP(pcb!=(int)sock_UCB->pcb, 27, "pcb at %d, but UCB.pcb at %d",pcb,(int)sock_UCB->pcb,0)
X
X pid = sock_UCB->PID;
X SETZAP(pid<=0 || pid>PID_MAX, 28, "Bad PID %d in UCB",pid,0,0)
X
X proc2_$upid_to_uid (pid, &p2_uid, &status);
X SETZAP(status.all, 31, "proc2_$upid_to_uid failed for PID %d with status %08x", pid&0xffff, status.all, 0)
X
#ifdef DEBUG
X printf ("process uid %08x.%08x\n", p2_uid.high, p2_uid.low);
X printf ("\n");
#endif /* DEBUG */
X
X proc2_$get_info (p2_uid, &p2_info, sizeof(p2_info), &status);
X SETZAP(status.all, 41, "proc2_$get_info failed on PID %d with status %08x", pid&0xffff, status.all, 0)
X
#ifdef DEBUG
X printf ("stack_uid %08x.%08x\n", p2_info.stack_uid.high, p2_info.stack_uid.low);
X printf ("stack_base %d\n", p2_info.stack_base);
X printf ("state %08x\n", p2_info.state);
X printf ("usr %d\n", p2_info.usr);
X printf ("upc %d\n", p2_info.upc);
X printf ("usp %d\n", p2_info.usp);
X printf ("usb %d\n", p2_info.usb);
X printf ("cpu_total %08x %04x\n", p2_info.cpu_total.high, p2_info.cpu_total.low);
X printf ("priority %d\n", p2_info.priority);
X printf ("sid.pers %08x.%08x\n", p2_info.sid.pers.high, p2_info.sid.pers.low);
X printf ("sid.proj %08x.%08x\n", p2_info.sid.proj.high, p2_info.sid.proj.low);
X printf ("sid.org %08x.%08x\n", p2_info.sid.org.high, p2_info.sid.org.low);
X printf ("sid.subs %08x.%08x\n", p2_info.sid.subs.high, p2_info.sid.subs.low);
X printf ("sid.node %x\n", p2_info.sid.node);
X printf ("pgroup %08x.%08x\n", p2_info.pgroup.high, p2_info.pgroup.low);
X printf ("is_server %d\n", p2_info.is_server);
X printf ("min_pri %d\n", p2_info.min_pri);
X printf ("max_pri %d\n", p2_info.max_pri);
X printf ("exec_faults %d\n", p2_info.exec_faults);
X printf ("data_faults %d\n", p2_info.data_faults);
X printf ("disk_pageIO %d\n", p2_info.disk_pageIO);
X printf ("net_pageIO %d\n", p2_info.net_pageIO);
X printf ("orig_pgroup %08x.%08x\n", p2_info.orig_pgroup.high, p2_info.orig_pgroup.low);
X printf ("orig_upgid %d\n", p2_info.orig_upgid);
X printf ("unix_PID %d\n", p2_info.unix_PID);
X printf ("unix_PPID %d\n", p2_info.unix_PPID);
X printf ("unix_PGID %d\n", p2_info.unix_PGID);
X printf ("udpid %d\n", p2_info.udpid);
X printf ("asid %d\n", p2_info.asid);
X printf ("acct_uid %08x.%08x\n", p2_info.acct_uid.high, p2_info.acct_uid.low);
X printf ("acct_len %d\n", p2_info.acct_len);
X printf ("acct_name %.*s\n", p2_info.acct_len, p2_info.acct_name);
X printf ("proc_len %d\n", p2_info.proc_len);
X printf ("proc_name %.*s\n", p2_info.proc_len, p2_info.proc_name);
X printf ("tty_uid %08x.%08x\n", p2_info.tty_uid.high, p2_info.tty_uid.low);
X printf ("cpu_time %08x %04x\n", p2_info.cpu_time.high, p2_info.cpu_time.low);
X printf ("user_ticks %d\n", p2_info.user_ticks);
X printf ("system_ticks %d\n", p2_info.system_ticks);
X printf ("tick_size %d\n", p2_info.tick_size);
X printf ("\n");
#endif /* DEBUG */
X
X SETZAP(p2_info.unix_PID!=pid, 42, "Looked up PID %d, but proc2_$get_info found %d", pid&0xffff, p2_info.unix_PID&0xffff, 0)
X
X /*
X for (p2_i = 0; p2_i < BUFLEN; p2_i++) retbuf[p2_i] = 0x00;
X rgyc_$sid2text (p2_info.sid, retbuf, &status);
X SETZAP(status.all, 51, "rgyc_$sid2text failed on person UID %08x.%08x with status %08x", p2_info.sid.pers.high, p2_info.sid.pers.low, status.all)
X */
X
X domain = 0;
X rgyc_$pgo_uid_to_num (domain, p2_info.sid.pers, &unknown, &unix_num, &status);
X SETZAP(status.all, 51, "rgyc_$pgo_uid_to_num failed on person UID %08x.%08x with status %08x", p2_info.sid.pers.high, p2_info.sid.pers.low, status.all)
X SETZAP(unix_num<0 || unix_num>UID_MAX, 52, "Bad unix UID %d from rgyc_$pgo_uid_to_num on person UID %08x.%08x",unix_num,p2_info.sid.pers.high,p2_info.sid.pers.low)
X
#ifdef DEBUG
X printf ("Unix UID: %d\n", unix_num);
X printf ("Unknown: %d\n", unknown);
X printf ("\n");
#endif /* DEBUG */
X
X *uid = unix_num;
X
#ifdef ALLOW_FORMAT
X *retpid = pid;
X
X name_$gpath_lc (p2_info.acct_uid, name_$junk_flag, name_$long_pnamlen_max, pname, &pnamlen, &status);
X /*
X * We can fail this with binaries removed,
X * or hard-linked and removed from original location.
X * So we fail gracefully...
X SETZAP(status.all, 61, "name_$gpath_lc failed on object UID %08x.%08x with status %08x", p2_info.acct_uid.high, p2_info.acct_uid.low, status.all)
X */
X if (status.all) {
X pnamlen = p2_info.acct_len;
X if (pnamlen > proc2_$aname_len) pnamlen = proc2_$aname_len;
X sprintf (pname, "%.*s (UID=%08x.%08x --> status=%08x)", pnamlen, p2_info.acct_name, p2_info.acct_uid.high, p2_info.acct_uid.low, status.all);
X pnamlen = strlen(pname);
X }
X else if (pnamlen < 1 || pnamlen > name_$long_pnamlen_max) {
X pnamlen = p2_info.acct_len;
X if (pnamlen > proc2_$aname_len) pnamlen = proc2_$aname_len;
X sprintf (pname, "%.*s (UID=%08x.%08x --> bad return length)", pnamlen, p2_info.acct_name, p2_info.acct_uid.high, p2_info.acct_uid.low);
X pnamlen = strlen(pname);
X }
X pname[pnamlen] = 0;
X
#ifdef DEBUG
X printf ("Command length: %d\n", pnamlen);
X printf ("Command name: %s\n", pname);
X printf ("\n");
#endif /* DEBUG */
X
X *retcmd = pname;
X
X context_$set (p2_uid, &status);
X SETZAP(status.all, 71, "context_$set failed on process UID %08x.%08x with status %08x", p2_uid.high, p2_uid.low, status.all)
X
X pgm_$context_get_args (&arg_count, &arg_vector_ptr, &status);
X /*
X * We can fail this for processes we do not 'own'.
X * So we fail gracefully...
X SETZAP(status.all, 81, "pgm_$context_get_args failed on process UID %08x.%08x with status %08x", p2_uid.high, p2_uid.low, status.all)
X */
X if (status.all) {
X pnamlen = p2_info.acct_len;
X if (pnamlen > proc2_$aname_len) pnamlen = proc2_$aname_len;
X sprintf (cmdarg, "%.*s (pgm_$context_get_args --> status=%08x)", pnamlen, p2_info.acct_name, status.all);
X pnamlen = strlen(cmdarg);
X }
X else {
X short i, j;
X
X int k1[2];
X void *k2;
X int k3;
X
X if (arg_count > 0) {
#ifdef DEBUG
X printf ("Argument count: %d\n", arg_count);
#endif /* DEBUG */
X pnamlen = 0;
X arg_ptr = arg_vector_ptr;
X for (i = 0; i< arg_count; i++, arg_ptr++) {
X /*
X ** For 'own' argument would simply have
X ** arg = *arg_ptr;
X ** But need to de-reference arg_ptr in context of other process,
X ** and then need to de-reference the arg pointer itself.
X */
X k1[0] = 0; k1[1] = 0; k3 = 0;
X xpd_$locate_proc (p2_uid, (void)arg_ptr, k1, &k2, &k3, &status);
X if (status.all) {
X pnamlen = p2_info.acct_len;
X if (pnamlen > proc2_$aname_len) pnamlen = proc2_$aname_len;
X sprintf (cmdarg, "%.*s (xpd_$locate_proc --> status=%08x)", pnamlen, p2_info.acct_name, status.all);
X pnamlen = strlen(cmdarg);
X break;
X }
X if (k3 != 0x070000) {
X pnamlen = p2_info.acct_len;
X if (pnamlen > proc2_$aname_len) pnamlen = proc2_$aname_len;
X sprintf (cmdarg, "%.*s (xpd_$locate_proc --> k3=%08x)", pnamlen, p2_info.acct_name, k3);
X pnamlen = strlen(cmdarg);
X break;
X }
X arg_ptr2 = k2;
X arg = *arg_ptr2;
X k1[0] = 0; k1[1] = 0; k3 = 0;
X xpd_$locate_proc (p2_uid, (void)arg, k1, &k2, &k3, &status);
X if (status.all) {
X pnamlen = p2_info.acct_len;
X if (pnamlen > proc2_$aname_len) pnamlen = proc2_$aname_len;
X sprintf (cmdarg, "%.*s (xpd_$locate_proc --> status=%08x)", pnamlen, p2_info.acct_name, status.all);
X pnamlen = strlen(cmdarg);
X break;
X }
X if (k3 != 0x070000) {
X pnamlen = p2_info.acct_len;
X if (pnamlen > proc2_$aname_len) pnamlen = proc2_$aname_len;
X sprintf (cmdarg, "%.*s (xpd_$locate_proc --> k3=%08x)", pnamlen, p2_info.acct_name, k3);
X pnamlen = strlen(cmdarg);
X break;
X }
X arg = k2;
X if (pnamlen > 0) { sprintf (&cmdarg[pnamlen], " "); pnamlen++; }
X j = arg->len;
X if (j + pnamlen > name_$long_pnamlen_max) j = name_$long_pnamlen_max - pnamlen;
X sprintf (&cmdarg[pnamlen], "%.*s", j, arg->chars);
X pnamlen += strlen (&cmdarg[pnamlen]);
X if (pnamlen+10 > name_$long_pnamlen_max) break;
X }
X }
X else {
X pnamlen = p2_info.acct_len;
X if (pnamlen > proc2_$aname_len) pnamlen = proc2_$aname_len;
X sprintf (cmdarg, "%.*s (pgm_$context_get_args --> no args)", pnamlen, p2_info.acct_name);
X pnamlen = strlen(cmdarg);
X }
X }
X
#ifdef DEBUG
X printf ("Cmd+args length: %d\n", pnamlen);
X printf ("Command+args: %s\n", cmdarg);
X printf ("\n");
#endif /* DEBUG */
X
X *retcmd_and_args = cmdarg;
X
X
/*
X * Do we need to set context back to our own with
X * context_$current (what arguments?) or
X * context_$set (our_own_Proc-UID) ?
*/
X
/*
X * Could we figure out environment with ev_$context_read_var_entry ?
X * Current (working) and home (naming) directories with name_$read_dirs_p ?
*/
X
X
#endif
X
X return (0);
X }
X }
X
X ZAP(1,zapmess,0)
X /* return (-1); */
}
X
SHAR_EOF
$shar_touch -am 0514055996 'pidentd-2.7/src/kernel/apollo.c' &&
chmod 0644 'pidentd-2.7/src/kernel/apollo.c' ||
$echo 'restore of' 'pidentd-2.7/src/kernel/apollo.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/kernel/apollo.c:' 'MD5 check failed'
4039e0a767fbe8dc81b175b14e67616c pidentd-2.7/src/kernel/apollo.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/apollo.c'`"
test 27026 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/kernel/apollo.c:' 'original size' '27026,' 'current size' "$shar_count!"
fi
fi
: || $echo 'restore of' 'pidentd-2.7/src/kernel/irix5.c' 'failed'
$echo 'End of part' '5,' 'continue with part' '6'
exit 0

Reply all
Reply to author
Forward
0 new messages