From:	CSBVAX::MRGATE!@KL.SRI.Com:zar@Hamlet.Caltech.Edu@SMTP 30-JUN-1987 10:25
To:	EVERHART
Subj:	Nanny Source V1.0 3/14

Received: from Hamlet.Caltech.Edu by KL.SRI.COM with TCP; Mon 29 Jun 87 17:31:48-PDT
Date:     Mon, 29 Jun 87 17:30:18 PDT
From:     zar@Hamlet.Caltech.Edu (Dan Zirin)
Message-Id: <870629173018.0m3@Hamlet.Caltech.Edu>
Subject:  Nanny Source V1.0 3/14
To:       info-vax@kl.sri.com

$!------------------------------Cut Here-------------------------
$ chk = "1279866454"
$ create build.com
$ deck/dollars="ThEgReAtZaR"
$ j = 0
$ k = 0
$ files = "nmain.for,nfunc.for,nannyacp.for,wakeacp.for,nanny.tex,nanny.inp"
$ lp: k = k + 1
$ lp1: i = f$locate(",",files)
$ file = f$extract(0,i,files)
$ if "''f$search(file)'".eqs."" then j = 1
$ if "''f$search(file)'".eqs."" then write sys$output "''file' doesn't exist"
$ if i.eq.f$length(files) then goto ed1
$ files = f$extract(i+1,f$length(files),files)
$ goto lp1
$ ed1: if k.eq.1 then files = "startnan.com,nanny.inc"
$ if k.eq.1 then goto lp
$ if j.ne.0 then write sys$output " "
$ if j.ne.0 then write sys$output "You haven't received the full Nanny"
$ if j.ne.0 then write sys$output "distribution yet. Try again later."
$ if j.ne.0 then exit %x2c
$ fortran/list=nanny/noopt/debug/object=nanny nmain+nfunc
$ link/nomap nanny
$ delete/nolog nanny.obj.
$ fortran/nolist/noopt/nodebug nannyacp
$ link/nomap nannyacp
$ delete/nolog nannyacp.obj.
$ fortran/nolist/noopt/nodebug wakeacp
$ link/nomap wakeacp
$ delete/nolog wakeacp.obj.
$!
$! Add next line to system login.com
$!
$ wake :== $'f$trnlnm("SYS$DISK")''f$directory()'wakeacp
$!
$ type sys$input:
Edit the files NANNY.INP and STARTNAN.COM. See NANNY.TEX for specifics
and limited help. To start things, type "@STARTNAN" (also insert this
in SYS$MANAGER:SYSTARTUP.COM). Run NANNYACP to talk to Nanny (send
requests) except for WAKE functions (use the WAKE command as defined
in BUILD.COM).

If you gets requests for Nanny, please try to inform the author (see
NMAIN.FOR for mail address). You should also try subscribing to nanny-users
where you may ask questions you have about Nanny and request additions.
To subscribe, send mail to the author (see NMAIN.FOR).

Remember: A VAX without a Nanny is like a child without a mother.

                                            From The Great
                                                 Zar
$ eod
ThEgReAtZaR
$ checksum build.com
$ if chk.nes.checksum$checksum then write sys$output -
  "BUILD.COM didn't pass checksum. File may be corrupted."
$ if chk.nes.checksum$checksum then exit %x2c
$ chk = "1128103364"
$ create startnan.com
$ deck/dollars="ThEgReAtZaR"
$ PRIORITY = F$GETSYI("DEFPRI") + 4
$ RUN CIT_SYSTEM:NANNY -
        /UIC = [1,4] -
        /PRIORITY = 'PRIORITY' -
        /INPUT = NANNY.INP -
        /OUTPUT = SYS$SCRATCH:NANNY.OUT -
        /ERROR = SYS$SCRATCH:NANNY.ERR -
        /AST_LIMIT = 40 -
        /BUFFER_LIMIT = 20480 -
        /IO_BUFFERED = 12 -
        /IO_DIRECT = 12 -
        /FILE_LIMIT = 20 -
        /WORKING_SET = 64 -
        /MAXIMUM_WORKING_SET = 1024 -
        /PAGE_FILE = 10240 -
        /QUEUE_LIMIT = 40 -
        /SUBPROCESS_LIMIT = 1 -
        /PRIVILEGES =(NOSAME, -
                ALLSPOOL,ALTPRI,CMEXEC,EXQUOTA,GROUP, -
		GRPNAM,LOG_IO,OPER,PRMMBX,SYSNAM, -
                SYSPRV,TMPMBX,VOLPRO,WORLD)
ThEgReAtZaR
$ checksum startnan.com
$ if chk.nes.checksum$checksum then write sys$output -
  "STARTNAN.COM didn't pass checksum. File may be corrupted."
$ if chk.nes.checksum$checksum then exit %x2c
$ chk = "90101888"
$ create nanny.inc
$ deck/dollars="ThEgReAtZaR"
C
C       (do not change this include file and expect things to fly on
C       the first go -- I suggest you consult me first as the include
C       file is new for VMS V4)
C
C       (c) Zar Ltd. 1985
C
        parameter       maxdisks       =   16
        parameter       maxig_term     =   16
        parameter       maxig_user     =   32
        parameter       maxpri         =   15
        parameter       maxuser        =  128
        parameter       max_average    =   10
        parameter       max_wake       =   25
        parameter       nan$_comdis    =  '1f'x
        parameter       nan$_invcom    =  '1d'x
        parameter       nan$_nonsys    =  '21'x
        parameter       nan$_nopriv    =  '20'x
        parameter       nan$_normal    =  '01'x
        parameter       nan$_noslot    =  '1b'x
        parameter       nan$_nosuchcom =  '1e'x
        parameter       nan$_retwarn   =  '1c'x
        parameter       nan$v_batch    =    0
        parameter       nan$v_detach   =    1
        parameter       nan$v_inter    =    2
        parameter       nan$v_network  =    3
        parameter       nan$v_subproc  =    4
        parameter       nan$v_unknown  =    5
        parameter       nan$_system    =    6
        parameter       opcom          = 'OPA0:'
        character*15    nan_prcnam
        character*12    c_username
        character*12    ig_user(maxig_user)
        character*10    c_phy_term
        character*10    c_terminal
        character*10    ig_term(maxig_term)
        character*8     c_account
        character*8     prefacc(maxuser)
        character*8     sysaccnam
        character*6     consoles(8)
        character*6     disks(maxdisks)
        integer*4       cpu_average
        integer*4       crush(maxuser)
        integer*4       crush_p
        integer*4       c_authpriv(2)
        integer*4       c_bufio
        integer*4       c_cpulim
        integer*4       c_cputim
        integer*4       c_dirio
        integer*4       c_owner
        integer*4       c_pageflts
        integer*4       c_ipid
        integer*4       c_pid
        integer*4       c_sts
        integer*4       c_wssize
        integer*4       disable
        integer*4       functmsk
        integer*4       ipid(maxuser)
        integer*4       lasterr(maxdisks)
        integer*4       lowdivd
        integer*4       lowphymem
        integer*4       low_free
        integer*4       maxelapsed
        integer*4       maxidle
        integer*4       maxphymem
        integer*4       minio
        integer*4       mintim
        integer*4       pid(maxuser)
        integer*4       ranjpipid
        integer*4       susp_ipid(maxuser)
        integer*4       susp_pid(maxuser)
        integer*4       suspids
        integer*4       sysgrp
        integer*4       truewait(2)
        integer*4       waitim
        integer*2       authpri(maxuser)
        integer*2       crpri(maxuser)
        integer*2       c_prccnt
        integer*2       c_prib
        integer*2       c_uic(2)
        integer*2       die
        integer*2       mbx2
        integer*2       mbx3
        integer*2       mbxchan
        integer*2       prib(maxuser)
        integer*2       system(maxuser)
        real*4          prefadd(maxuser)
        logical*1       debugging
        logical*1       dsk_die
        logical*1       inbuff(128)
        logical*1       listen
        logical*1       purgews
        logical*1       startup_flg
        common/diecom/  authpri,crush,crpri,crush_p,prib,debugging
        common/dsk_com/ dsk_die,disks,low_free,lasterr
        common/jpicom_i/c_authpriv,c_bufio,c_cpulim,c_cputim,c_dirio,
     1                  c_owner,c_pageflts,c_ipid,c_pid,c_prccnt,
     2                  c_prib,c_sts,c_uic,c_wssize,ranjpipid
        common/jpicom_s/c_account,c_phy_term,c_terminal,c_username
        common/nanny/   mbx2,mbx3,die,mbxchan,inbuff,ipid,pid,disable,
     1                  system
        common/nanopr/  consoles,listen
        common/param/   sysgrp,waitim,cpu_average,maxidle,maxelapsed,
     1                  mintim,minio,truewait,lowdivd,purgews,maxphymem,
     2                  lowphymem,functmsk,prefadd
        common/param1/  sysaccnam,nan_prcnam,ig_user,ig_term,prefacc
        common/strtup/  startup_flg
        common/susped/  susp_ipid,susp_pid,suspids
ThEgReAtZaR
$ checksum nanny.inc
$ if chk.nes.checksum$checksum then write sys$output -
  "NANNY.INC didn't pass checksum. File may be corrupted."
$ if chk.nes.checksum$checksum then exit %x2c
$ chk = "1764699561"
$ create nanny.inp
$ deck/dollars="ThEgReAtZaR"
Nanny             !The process name to use
010               !Any group =< this number is ignored (3 digit octal)
SYSTEM            !The system account name
3000              !Time interval to wait between cycles (30 sec)
3                 !# of Nanny cycles for CPU averaging (3 cycles or 1.5min)
120,2400          !Maxidle time and Maxelapsed (1hr and 20hr)
5,1               !CPU, I/O needed to be non-idle (0.05 sec CPU, 1 I/O)
0                 !Using more than this much memory, allow suspending
0                 !Resume jobs if only using less than this much memory
NO                !Should we purge working set after cycles
50                !If maxblocks/"this value" > freeblocks, send disk full warn
SYS$SYSDEVICE:    !Check these disks for low space (<1/"above line" space left)
                  !Extra ttys to send Nanny messages to
00000202          !Command disable mask (hex) -- DIE + NEW commands enabled
80000000          !Function enable mask (bit 31 or 32 set=DEBUG(hex))
                  !Users to ignore
OPA0:,TTA0:       !Terminals to ignore
ThEgReAtZaR
$ checksum nanny.inp
$ if chk.nes.checksum$checksum then write sys$output -
  "NANNY.INP didn't pass checksum. File may be corrupted."
$ if chk.nes.checksum$checksum then exit %x2c
$ chk = "1449984708"
$ create nf2.for
$ deck/dollars="ThEgReAtZaR"
C
C======================================================================
C
c
c       (c) Zar Ltd. 1985
c
        integer*4 function len1(str)
        character*(*)   str
        i = lench(str)
        if (i.eq.0) i = 1
        len1 = i
        return
        end
        subroutine      alloc(inline,dumy)
c
c       Routine to allocate or deallocate devices to keep users
c       from accessing them.
c
c       (c) Zar Ltd. 1985
c
        parameter       nan$_invcom  = '1d'x
        parameter       nan$_nopriv  = '20'x
        parameter       nan$_retwarn = '1c'x
        implicit        integer*4 (a-z)
        include         '($ssdef)'
        character*(*)   inline
        character*20    devnam,phydevnam
        character*4     funct
        logical*1       dumy
c
c       Get the command
c
        dumy = nan$_invcom
        if (lench(inline).eq.0) goto 999
        do while(inline(1:1).eq.' ')
         inline=inline(2:)
        end do
        i=index(inline,' ')-1
        if (i.lt.1) goto 999
        funct=inline(:i)
        call str$upcase(funct,funct)
c
c       Get the device to allocate or deallocate
c
        inline=inline(i+2:)
        if (lench(inline).eq.0) goto 999
        do while(inline(1:1).eq.' ')
         inline=inline(2:)
        end do
        i=index(inline,' ')-1
        if (i.lt.1.or.i.gt.20) goto 999
        devnam=inline(:i)
        if (lench(devnam).eq.0) goto 999
c
c       Do the dirty deed
c
        if (funct.eq.'GRAB') then
          code = sys$alloc(devnam(:len1(devnam)),dev_l,phydevnam,,)
        else if (funct.eq.'FREE') then
          code = sys$dalloc(devnam(:len1(devnam)),)
        else
          goto 999
        end if
        if (bug(code,'ALLOC').ne.ss$_normal) goto 999
c
c       Write out an appropriate message
c
        if (funct.eq.'GRAB') then
          call output(2,phydevnam(:dev_l)//' has been allocated and '//
     1    'is no longer available')
        else
          call output(2,phydevnam(:dev_l)//' has been deallocated and'//
     1    ' is available for use')
        end if
        dumy = 1
        return
c
c       An error occurred
c
999     call output(1,'Unable to '//funct//' device '//devnam(:len1(
     1  devnam)))
        return
        end
        subroutine      boost
c
c       Return all processes to what we think their authorized
c       priority is.
c
c       (c) Zar Ltd. 1985
c
        implicit        integer*4 (a-z)
        include         'nanny.inc'
        include         '($ssdef)'
c
c       Loop for processes
c
        do i=1,crush_p
         if (crush(i).ne.0) then
           pt = ipid(i)
           if (system(pt).ne.nan$v_inter.and.system(pt).ne.
     1     nan$v_subproc) then
             code = sys$setpri(crush(i),,%val(crpri(i)),)
             if (code.ne.ss$_nonexpr.and.code.ne.ss$_normal) then
               call bug(code,'SETPRI')
               call output(1,'Unable to reset a specific priority')
             else
               prib(pt) = crpri(i)
             end if
           end if
           crush(i) = 0
           crpri(i) = 0
         end if
        end do
        crush_p = 0
        return
        end
ThEgReAtZaR
$ checksum nf2.for
$ if chk.nes.checksum$checksum then write sys$output -
  "NF2.FOR didn't pass checksum. File may be corrupted."
$ if chk.nes.checksum$checksum then exit %x2c
$ exit
