#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  Make.renice renice.c
# Wrapped by brant@manta on Tue Feb 14 14:44:48 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Make.renice' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Make.renice'\"
else
echo shar: Extracting \"'Make.renice'\" \(237 characters\)
sed "s/^X//" >'Make.renice' <<'END_OF_FILE'
Xinclude $(MAKEINC)/Makepre.h
XSHELL=/bin/sh
XINSTALL=mv
XLBIN=/usr/local/bin
XCFLAGS=-O -c
X
Xrenice : renice.c
X	$(CC) $(CFLAGS) renice.c
X	$(LD) $(SHAREDLIB) -o renice renice.o
X	chmod 4755 renice
X	chown root renice
X	$(INSTALL) renice $(LBIN)
X
END_OF_FILE
if test 237 -ne `wc -c <'Make.renice'`; then
    echo shar: \"'Make.renice'\" unpacked with wrong size!
fi
# end of 'Make.renice'
fi
if test -f 'renice.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'renice.c'\"
else
echo shar: Extracting \"'renice.c'\" \(4916 characters\)
sed "s/^X//" >'renice.c' <<'END_OF_FILE'
X/************************************************************
X *
X * This program was written by me, Mike "Ford" Ditto, and
X * I hereby release it into the public domain in the interest
X * of promoting the development of free, quality software
X * for the hackers and users of the world.
X *
X * Feel free to use, copy, modify, improve, and redistribute
X * this program, but keep in mind the spirit of this
X * contribution; always provide source, and always allow
X * free redistribution (shareware is fine with me).  If
X * you use a significant part of this code in a program of
X * yours, I would appreciate being given the appropriate
X * amount of credit.
X *				-=] Ford [=-
X *
X ************************************************************/
X
X#include <stdio.h>
X#include <fcntl.h>
X#include <ctype.h>
X#include <errno.h>
X#include <pwd.h>
X#include <grp.h>
X#include <sys/types.h>
X#include <sys/param.h>
X#include <sys/tune.h>
X#include <sys/proc.h>
X#include <nlist.h>
X
X
Xextern long lseek();
Xextern void perror(), exit();
X
X
Xvoid kcopy(), kwrite();
X
Xchar *progname;
X
X#define tuhiaddr (mysyms[0].n_value)
X#define procaddr (mysyms[1].n_value)
X
Xstruct nlist mysyms[] =
X{
X    { "tuhi", },
X    { "proc", },
X    { (char *)0, },
X};
X
Xchar buf[BUFSIZ];
X
Xint kmem;
Xint myuid;
Xint NPROC;
Xstatic struct proc proc;
X
X
Xvoid usage()
X{
X    fprintf(stderr,
X	    "usage:	%s [{+-}inc] [=prio] pid ...\n", progname);
X    exit(-1);
X}
X
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X    int status=0;
X    int pid, relative, value;
X
X    progname = *argv;
X
X    setup();
X
X    relative = 1;
X    value = 5;
X
X    while (++argv,--argc)
X	switch (argv[0][0])
X	{
X	case '-':
X	    if (sscanf(argv[0]+1, "%d", &value) != 1)
X		usage();
X	    relative = 1;
X	    break;
X	case '+':
X	    if (sscanf(argv[0]+1, "%d", &value) != 1)
X		usage();
X	    value = -value;
X	    relative = 1;
X	    break;
X	case '=':
X	    if (sscanf(argv[0]+1, "%d", &value) != 1)
X		usage();
X	    relative = 0;
X	    break;
X	default:
X	    if (sscanf(argv[0], "%d", &pid) != 1)
X		usage();
X	    status += renice(pid, value, relative);
X	}
X
X    return status;
X}
X
X
X/* one-time setup of main data structures from the kernel */
Xsetup()
X{
X    struct tunable tune;
X
X    if ( (kmem=open("/dev/kmem", O_RDWR)) < 0 )
X    {
X	sprintf(buf, "%s: can't open /dev/kmem", progname);
X	perror(buf);
X	exit(1);
X    }
X
X    if (nlist("/unix", mysyms))
X    {
X	sprintf(buf, "%s: can't nlist /unix", progname);
X	perror(buf);
X	exit(1);
X    }
X
X    myuid = getuid();
X    setuid(myuid);
X
X#ifdef DEBUG
X    fprintf(stderr, "tuhi:	0x%08lx\n", tuhiaddr);
X#endif DEBUG
X    kcopy((char *)&tune, tuhiaddr, (long) sizeof tune);
X
X    /* do indirection on the proc address, since it */
X    /* is just a pointer in the kernel */
X    kcopy((char *)&procaddr, procaddr, (long) sizeof procaddr);
X
X#ifdef DEBUG
X    fprintf(stderr, "proc:	0x%08lx\n", procaddr);
X#endif DEBUG
X
X    NPROC = tune.nproc;
X
X#ifdef DEBUG
X    fprintf(stderr, "NPROC:	%d\n", NPROC);
X#endif DEBUG
X}
X
X
X/* copy bytes from kernel address space to this process */
Xvoid kcopy(caddr, kaddr, nbytes)
Xchar *caddr;
Xlong kaddr;
Xlong nbytes;
X{
X    if ( lseek(kmem, kaddr, 0)<0L ||
X	read(kmem, caddr, (unsigned)nbytes) != nbytes )
X    {
X	sprintf(buf, "%s: can't read /dev/kmem", progname);
X	perror(buf);
X	exit(1);
X    }
X}
X
X
X/* write bytes from this process' address space to the kernel's */
Xvoid kwrite(kaddr, caddr, nbytes)
Xlong kaddr;
Xchar *caddr;
Xlong nbytes;
X{
X#ifdef DEBUG
X    fprintf(stderr, "Writing %ld bytes to kernel address 0x%08lx\n",
X	    nbytes, kaddr);
X#endif
X
X    if ( lseek(kmem, kaddr, 0)<0L ||
X	write(kmem, caddr, (unsigned)nbytes) != nbytes )
X    {
X	sprintf(buf, "%s: can't write /dev/kmem", progname);
X	perror(buf);
X	exit(1);
X    }
X}
X
X
X/* change the nice value of process `pid' based on 'value' and 'relative' */
Xrenice(pid, value, relative)
Xint pid, value, relative;
X{
X    register i;
X    int tmpnice;
X
X    for ( i=0 ; i<NPROC ; ++i )
X    {
X	kcopy((char *)&proc,
X	      (long)&((struct proc *)procaddr)[i],
X	      (long)sizeof proc);
X	if ( proc.p_pid == pid )
X	{
X#ifdef DEBUG
X	    fprintf(stderr, "Found it!  proc[%d], p_uid is %d\n",
X		   i, proc.p_uid);
X
X	    fprintf(stderr, "Old p_nice was %d\n", proc.p_nice);
X#endif DEBUG
X
X	    tmpnice = proc.p_nice;
X
X	    if (relative)
X		tmpnice += value;
X	    else
X		tmpnice = value;
X
X	    if (tmpnice >= 40)
X		tmpnice = 40;
X	    if (tmpnice < 0)
X		tmpnice = 0;
X
X#ifdef DEBUG
X	    fprintf(stderr, "New p_nice is %d\n", tmpnice);
X#endif DEBUG
X
X	    if ( myuid && (myuid != proc.p_uid || tmpnice<proc.p_nice) )
X	    {
X		errno = EACCES;
X		sprintf(buf, "%s: can't renice process %d", progname, pid);
X		perror(buf);
X		return 1;
X	    }
X
X	    proc.p_nice = tmpnice;
X
X	    kwrite((long)&((struct proc *)procaddr)[i]
X		   + ( ((char *)&proc.p_nice) - (char *)&proc ),
X		   (char *)&proc.p_nice,
X		   (long)sizeof proc.p_nice);
X	    return 0;
X	}
X    }
X
X    fprintf(stderr, "%s: process %d not found.\n", progname, pid);
X
X    return 1;
X}
END_OF_FILE
if test 4916 -ne `wc -c <'renice.c'`; then
    echo shar: \"'renice.c'\" unpacked with wrong size!
fi
# end of 'renice.c'
fi
echo shar: End of shell archive.
exit 0

