Prereq: 339
*** ../netlib/pvm3.3.9/src/patchlevel.h	Fri Sep  8 13:58:55 1995
--- src/patchlevel.h	Thu Nov  2 10:03:36 1995
***************
*** 1,3 ****
  
! #define PATCHLEVEL 339
  
--- 1,3 ----
  
! #define PATCHLEVEL 3310
  
*** ../netlib/pvm3.3.9/Readme	Sun Oct 16 05:30:43 1994
--- Readme	Thu Nov  2 10:47:58 1995
***************
*** 50,74 ****
  Files in the distribution unpack in directory pvm3.  The pvm3 directory
  can reside in either a private or shared disk area.  Installations for
  multiple machine architectures can coexist because compiled files are
! placed in subdirectories named for each architecture.
  
      Directory   Contains
      ---------------------------------------------------------------
!     bin/ARCH    System PVM executables
!     conf        Configuration files for the PVM architectures
      console     Source for the pvm console
      doc         Miscellaneous documentation
!     examples    Example PVM programs
      gexamples   More example PVM programs - for group library
      hoster      An example "hoster" program
      include     Header files for PVM programs
      lib         Generic system executables (scripts)
!     lib/ARCH    System executables
      libfpvm     Source for the libfpvm Fortran library
!     man         Online manual pages (nroff format)
!     patches     Patch files, as released
      pvmgs       Source for the libgpvm library and group nameserver
      src         Source for the libpvm library and pvmd daemon
      tasker      An example "tasker" program
      xep         An example interactive X-Window program
  
--- 50,78 ----
  Files in the distribution unpack in directory pvm3.  The pvm3 directory
  can reside in either a private or shared disk area.  Installations for
  multiple machine architectures can coexist because compiled files are
! placed in subdirectories named for each architecture (ARCH).
  
+ Some of the more important directories are:
+ 
      Directory   Contains
      ---------------------------------------------------------------
!     bin/ARCH    PVM user program executables (the examples or your programs)
!     conf        Make configuration files for all PVM architectures
      console     Source for the pvm console
      doc         Miscellaneous documentation
!     examples    Example PVM program source
      gexamples   More example PVM programs - for group library
      hoster      An example "hoster" program
      include     Header files for PVM programs
      lib         Generic system executables (scripts)
!     lib/ARCH    System executables (pvmd, console, etc.)
      libfpvm     Source for the libfpvm Fortran library
!     man/man[13] Online manual pages (nroff format)
!     misc        Some PVM examples and utilities
!     patches     Patch files and instructions, as they are released
      pvmgs       Source for the libgpvm library and group nameserver
      src         Source for the libpvm library and pvmd daemon
+     src/ARCH    Additional source code for specific machines
      tasker      An example "tasker" program
      xep         An example interactive X-Window program
  
***************
*** 84,91 ****
  
      setenv PVM_ROOT $HOME/pvm3
  
! to your .cshrc file.  If you use a shell that reads .profile, add the
! following lines to that file:
  
      PVM_ROOT=$HOME/pvm3
      PVM_DPATH=$PVM_ROOT/lib/pvmd
--- 88,95 ----
  
      setenv PVM_ROOT $HOME/pvm3
  
! to your .cshrc file.  If you use a shell that reads .profile, such as sh
! or ksh, add the following lines to that file:
  
      PVM_ROOT=$HOME/pvm3
      PVM_DPATH=$PVM_ROOT/lib/pvmd
***************
*** 143,151 ****
  
  CONTACT
  
  Please direct any e-mail (questions, bugs, bug fixes, etc.) to:
  
      pvm@msr.EPM.ORNL.GOV.
  
! A newsgroup, comp.parallel.pvm, exists for discussion about PVM.
  
--- 147,169 ----
  
  CONTACT
  
+ The PVM web home page is at
+ 
+     http://www.epm.ornl.gov/pvm/pvm_home.html .
+ 
+ A newsgroup, comp.parallel.pvm, exists for discussion about PVM
+ and help with problems.
+ 
  Please direct any e-mail (questions, bugs, bug fixes, etc.) to:
  
      pvm@msr.EPM.ORNL.GOV.
  
! To report bugs or problems with PVM, please see the file
! 
!     $PVM_ROOT/doc/bugreport .
! 
! ________________________________________________________________________
! 
! Sincerely,
! The PVM research group
  
*** ../netlib/pvm3.3.9/Readme.mp	Mon Jun 12 14:29:09 1995
--- Readme.mp	Thu Nov  2 11:57:35 1995
***************
*** 5,40 ****
  Table of Contents
  -----------------
  
! 1. Multiprocessor Architectures vs. Workstation Clusters
! 2. iPSC/860
! 3. Paragon
! 4. CM5
! 5. Shared-memory Systems
  	Solaris 2.3
  	SGI 5.1
- 6. IBM SP2
  
  
! 1. Multiprocessor Architectures vs. Workstation Clusters
! --------------------------------------------------------
  
- 	This software is based on (and compatible with) version 3.3. 
- 
  	In the workstation environment, there is usually one (or a few at
  the most) task(s) and one PVM Daemon (pvmd) on each host. On a MPP
  machine, however, only one pvmd runs on the front-end and it has to
! support all the tasks running on the nodes. Node-to-node messages are 
! sent directly across and very fast, but packets going to another 
! machine (or between tasks not spawned together in the case of the CM5
! and IBM SP2) must be relayed by pvmd and that link is slow, especially for
! large messages.
  
! 	On a MPP machine tasks are always spawned on the nodes. If you
! want to start a task on the front-end you have to run it as a Unix
! process, which then connects to the pvmd by calling pvm_mytid().
! However node processes not loaded by PVM are not allowed to
! enrolled.
  
  	The system supports on nodes of some MPP machines are limited.
  For example if your program forks on a node, the behavior of the new
  process is machine-dependent. In any event it would not be allowed
--- 5,53 ----
  Table of Contents
  -----------------
  
! 1. MPP vs. Workstation Cluster
! 2. Usage
! 3. iPSC/860
! 4. Paragon
! 5. CM5
! 6. IBM SP2
! 7. Shared-memory Systems
  	Solaris 2.3
  	SGI 5.1
  
  
! 1. Massively Parallel Systems vs. Workstation Cluster
! -----------------------------------------------------
  
  	In the workstation environment, there is usually one (or a few at
  the most) task(s) and one PVM Daemon (pvmd) on each host. On a MPP
  machine, however, only one pvmd runs on the front-end and it has to
! support all the tasks running on the back-end nodes. On an SP2, the
! node on which PVM is started becomes the front-end.
  
! 	On a MPP machine tasks are always spawned on the back-end nodes.
! If you want to start a task on the front-end you have to run it as a 
! Unix process, which then connects to the pvmd by calling pvm_mytid(). 
! Tasks to be run on the front-end should be linked with the socket-
! based libpvm3.a (i.e., compiled with the option "-lpvm3"), while tasks
! to be spawned on the back-end must be linked with libpvm3pe.a (i.e.,
! compiled with the option "-lpvm3pe").
  
+ 	On the Paragon, tasks running on the back-end communicate with
+ one another directly, but packets going to another machine or to a
+ task on the front-end must be relayed by pvmd. To get the best 
+ performance, the entire program should run on the back-end. If you 
+ must have a master task running on the front-end (to read input from 
+ the user terminal, for example), the master should avoid doing any 
+ compute-intensive work.
+ 
+     On the CM5 and SP2, each batch of tasks created by pvm_spawn() 
+ form a unit. Within the same unit, message are passed directly. For 
+ each unit, PVM spawns an additional task to relay messages to and from 
+ pvmd, because tasks in the unit cannot communicate with pvmd directly. 
+ Communication between different units must go through pvmd. To get the
+ best performance, try to spawn all your tasks together.
+ 
  	The system supports on nodes of some MPP machines are limited.
  For example if your program forks on a node, the behavior of the new
  process is machine-dependent. In any event it would not be allowed
***************
*** 41,53 ****
  to become a new PVM task. 
  
  	Inter-host task-to-task direct routing via a TCP socket connection 
! has not been implemented on the nodes. Calling pvm_advise() on a node
! has no effect. 
  
  	PVM message tags above 999999000 are reserved for internal use.
  
  
! 2. iPSC/860
  -----------
  
  	This port was developed on an iPSC/860 with 128 nodes, using an
--- 54,134 ----
  to become a new PVM task. 
  
  	Inter-host task-to-task direct routing via a TCP socket connection 
! has not been implemented on the nodes. Setting the PvmRouteDirect option
! on a node has no effect. 
  
  	PVM message tags above 999999000 are reserved for internal use.
  
+     You should not have to make any changes in your source code when you
+ move your PVM program from a workstation cluster to a MPP, unless your
+ program contains machine-dependent code. You do need to, however, modify
+ the makefile to link in the approriate libraries. In the examples 
+ directory, you'll find a special makefile for each MPP architecture, 
+ hidden under the ARCH directory. On some MPP you must use a special 
+ compiler or loader to compile your program.
  
! 
! 
! 2. Usage
! --------
! 
!     Once properly installed, PVM can be started on a MPP by simply typing 
! pvm or pvmd&. Although a MPP has many nodes, it is treated as a single 
! host in PVM, just like a workstation. PVM has access to all the nodes in
! the default partition. To run a program in parallel, the user spawns a 
! number of tasks, which will be loaded onto different nodes by PVM. The 
! user has no control of how the tasks are distributed among the nodes.
! So running a parallel program on a MPP is like running it on a very 
! powerful uniprocessor machine with multitasking. For example, to run 
! nntime program on the IBM SP2, we first start PVM on the high performance
! switch, and then spawn 2 copies of nntime from the console:
! 
! r25n15% pvm3/lib/pvm -nr25n15-hps
! pvm> conf
! 1 host, 1 data format
!                     HOST     DTID     ARCH   SPEED
!               r25n15-hps    40000   SP2MPI    1000
! pvm> spawn -2 -> nntime
! [1]
! 2 successful
! t60000
! t60001
! pvm> [1:t60000] t60001: 100000 doubles received correctly
! [1:t60000] 
! [1:t60000] 
! [1:t60000] t60000: 100000 doubles received correctly
! [1:t60000] 
! [1:t60000] 
! [1:t60000] Node-to-node Send/Ack
! [1:t60000] 
! [1:t60000] Roundtrip T = 90 (us)  (0.0000 MB/s)      Data size: 0
! [1:t60000] Roundtrip T = 105 (us)  (1.5238 MB/s)      Data size: 80
! [1:t60000] Roundtrip T = 207 (us)  (7.7295 MB/s)      Data size: 800
! [1:t60000] Roundtrip T = 920 (us)  (17.3913 MB/s)      Data size: 8000
! [1:t60000] Roundtrip T = 5802 (us)  (27.5767 MB/s)      Data size: 80000
! [1:t60000] Roundtrip T = 47797 (us)  (33.4749 MB/s)      Data size: 800000
! [1:t60001] EOF
! [1:t60000] EOF
! [1] finished
! pvm> halt
! r25n15%
! 
!     There is no need to "add" any nodes, "conf" showed only one host. We 
! note that nntime is a true "hostless" program in the sense that it has
! no master task. The spmd example, on the other hand, has a master
! task which spawns other slave tasks. Hostless programs perform better
! than master-slave programs because all the tasks can be spawned together
! onto back-end nodes.
! 
!     PVM does not distinguish between a multiprocessor system and a
! uniprocessor system. While machine-specific information such as the
! number of processors and the power of individual processor would be 
! useful for load-balancing purpose, PVM neither supplies nor makes use
! of such information. 
! 
! 
! 
! 3. iPSC/860
  -----------
  
  	This port was developed on an iPSC/860 with 128 nodes, using an
***************
*** 92,140 ****
  
  BUGS AND TIPS
  
! 	1. On the SRM pvm is slow to start and it may sometimes time out and
  print out the message "can't start pvmd", while in fact pvmd has already
  been started. When this happens, just run pvm again and it'll connect
  to the pvmd. If you start the pvm console on another machine and add the
  I860 host to the configuration then this should not occur.
  
! 	2. To use PVM on a remote host you have to start "pvm3/lib/I860/pvmd"
  manually in the background, because PVM has no way of knowing that your
  workstation is being used as a front-end to the hypercube. PVM relies on
  the shell script "pvm3/lib/pvmd" to determine the architecture of your
  system, you can hack the script to make it do what you want.
  
! 	3. If PVM cannot obtain a cube of the size you specify because none
  is available, it will return the error "Out of resources".
  
! 	4. The function pvm_spawn() will NOT return until all spawned tasks
  check in with PVM. Therefore slave tasks should call pvm_mytid() before
  starting any heavy duty computation.
  
! 	5. The only signal that can be sent to tasks running on the cube is
  SIGKILL. Any other signals will be ignored.
  
! 	6. All spawned tasks should call pvm_exit() just before they exit.
  Pvmd will release the cube after all tasks loaded into the cube have
  called pvm_exit(). If any task attempts to continue execution after
  it called pvm_exit(), it'll be terminated when the cube is released.
  
! 	7. There is a constant TIMEOUT in the file "pvmmimd.h" that controls 
  the frequency at which the PVM daemon probes for packets from node tasks.
  If you want it to respond more quickly you can reduce this value. 
  Currently it is set to 10 millisecond.
  
! 	8. DO NOT use any native NX message passing calls in PVM or they
  may interfere with pvm_send()/pvm_recv().
  
! 	9. Messages printed to "stderr" by node tasks do not end up in
  the log file "/tmp/pvml.uid".
  
! 	10. The "argv" argument to pvm_spawn() is quietly ignored.
  
  
  
! 3. Paragon
  ----------
  
  	This port has been tested on a Paragon XPS5 running R1.3. The support
--- 173,221 ----
  
  BUGS AND TIPS
  
! 	a) On the SRM pvm is slow to start and it may sometimes time out and
  print out the message "can't start pvmd", while in fact pvmd has already
  been started. When this happens, just run pvm again and it'll connect
  to the pvmd. If you start the pvm console on another machine and add the
  I860 host to the configuration then this should not occur.
  
! 	b) To use PVM on a remote host you have to start "pvm3/lib/I860/pvmd"
  manually in the background, because PVM has no way of knowing that your
  workstation is being used as a front-end to the hypercube. PVM relies on
  the shell script "pvm3/lib/pvmd" to determine the architecture of your
  system, you can hack the script to make it do what you want.
  
! 	c) If PVM cannot obtain a cube of the size you specify because none
  is available, it will return the error "Out of resources".
  
! 	d) The function pvm_spawn() will NOT return until all spawned tasks
  check in with PVM. Therefore slave tasks should call pvm_mytid() before
  starting any heavy duty computation.
  
! 	e) The only signal that can be sent to tasks running on the cube is
  SIGKILL. Any other signals will be ignored.
  
! 	f) All spawned tasks should call pvm_exit() just before they exit.
  Pvmd will release the cube after all tasks loaded into the cube have
  called pvm_exit(). If any task attempts to continue execution after
  it called pvm_exit(), it'll be terminated when the cube is released.
  
! 	g) There is a constant TIMEOUT in the file "pvmmimd.h" that controls 
  the frequency at which the PVM daemon probes for packets from node tasks.
  If you want it to respond more quickly you can reduce this value. 
  Currently it is set to 10 millisecond.
  
! 	h) DO NOT use any native NX message passing calls in PVM or they
  may interfere with pvm_send()/pvm_recv().
  
! 	i) Messages printed to "stderr" by node tasks do not end up in
  the log file "/tmp/pvml.uid".
  
! 	j) The "argv" argument to pvm_spawn() is quietly ignored.
  
  
  
! 4. Paragon
  ----------
  
  	This port has been tested on a Paragon XPS5 running R1.3. The support
***************
*** 172,178 ****
  pvmd should be started first, and then the console may be started:
         % pvmd -sz <partsize> & 
         % pvm
! Other hosts, including other Paragons, may then be add using the console.
         pvm> add other_pgon
         pvm> add my_workstation
         
--- 253,259 ----
  pvmd should be started first, and then the console may be started:
         % pvmd -sz <partsize> & 
         % pvm
! Other hosts, including other Paragons, may then be added using the console.
         pvm> add other_pgon
         pvm> add my_workstation
         
***************
*** 180,186 ****
  
      Host (master) programs should be linked with pvm3/lib/PGON/libpvm3.a
  and the system library librpc.a, node (slave) programs with
! pvm3/lib/PGON/libpvm3pe.a, libnx.a, and librpc.a .  Fortran programs should
  also be linked with pvm3/lib/PGON/libfpvm3.a .
  
  	The programs in the gexamples directory have NOT been ported. The
--- 261,267 ----
  
      Host (master) programs should be linked with pvm3/lib/PGON/libpvm3.a
  and the system library librpc.a, node (slave) programs with
! pvm3/lib/PGON/libpvm3pe.a, libnx.a, and librpc.a . Fortran programs should
  also be linked with pvm3/lib/PGON/libfpvm3.a .
  
  	The programs in the gexamples directory have NOT been ported. The
***************
*** 191,200 ****
      If possible, native mode collective operations such as gsync,
  gisum, and gdsum are used for group operations.  The native operations
  will be used if all of following hold 
!       1) A native collective operation exists on the Paragon
!       2) All the nodes in the paragon compute partition are participating
           in the collective operation (pvm_barrier, pvm_reduce, etc.)
!       3) The group has been made static with pvm_freezegroup
  
  If all three conditions do not hold, the collective operation still functions
  correctly, but does not use native operations. If all the PGON nodes are part
--- 272,281 ----
      If possible, native mode collective operations such as gsync,
  gisum, and gdsum are used for group operations.  The native operations
  will be used if all of following hold 
!       a) A native collective operation exists on the Paragon
!       b) All the nodes in the paragon compute partition are participating
           in the collective operation (pvm_barrier, pvm_reduce, etc.)
!       c) The group has been made static with pvm_freezegroup
  
  If all three conditions do not hold, the collective operation still functions
  correctly, but does not use native operations. If all the PGON nodes are part
***************
*** 203,213 ****
  
  BUGS AND CAVEATS
  
! 	1. Tasks spawned onto the Paragon run on the compute nodes by default.
! Host processes run on the service nodes and should be started from a Unix
  prompt.
  
! 	2. By default PVM spawns tasks in your default partition. You can use
  the NX command-line options such as "-pn partition_name" to force it to
  run on a particular partition or "-sz number_of_nodes" to specify the
  number of nodes you want it to use. Setting the environmental variable 
--- 284,294 ----
  
  BUGS AND CAVEATS
  
! 	a) Tasks spawned onto the Paragon run on the compute nodes by default.
! Host tasks run on the service nodes and should be started from a Unix
  prompt.
  
! 	b) By default PVM spawns tasks in your default partition. You can use
  the NX command-line options such as "-pn partition_name" to force it to
  run on a particular partition or "-sz number_of_nodes" to specify the
  number of nodes you want it to use. Setting the environmental variable 
***************
*** 217,242 ****
  would force it to run on the partition "pvm" using only 33 nodes (there
  must be at least that many nodes in the partition).
  
! 	3. The current implementation only allows one task to be spawned on
  each node.
  
! 	4. There is a constant TIMEOUT in the file "pvmmimd.h" that controls 
  the frequency at which the PVM daemon probes for packets from node tasks. 
  If you want it to respond more quickly you can reduce this value. 
  Currently it is set to 10 millisecond.
  
! 	5. DO NOT use any native NX message passing calls in PVM or they
  may interfere with pvm_send()/pvm_recv().
  
! 	6. Messages printed to "stderr/stdout" by node tasks do not end up in
! the log file "/tmp/pvml.uid".
! 
! 	7. PVM programs compiled for versions earlier than 3.3.8 need to
  be recompiled.  A small change in data passed to node tasks on startup
  will cause earlier programs to break. 
  
  
! 4. CM5
  ------
  
  	This port was developed on a 32-node CM5 running CMOST v7.2 and
--- 298,320 ----
  would force it to run on the partition "pvm" using only 33 nodes (there
  must be at least that many nodes in the partition).
  
! 	c) The current implementation only allows one task to be spawned on
  each node.
  
! 	d) There is a constant TIMEOUT in the file "pvmmimd.h" that controls 
  the frequency at which the PVM daemon probes for packets from node tasks. 
  If you want it to respond more quickly you can reduce this value. 
  Currently it is set to 10 millisecond.
  
! 	e) DO NOT use any native NX message passing calls in PVM or they
  may interfere with pvm_send()/pvm_recv().
  
! 	f) PVM programs compiled for versions earlier than 3.3.8 need to
  be recompiled.  A small change in data passed to node tasks on startup
  will cause earlier programs to break. 
  
  
! 5. CM5
  ------
  
  	This port was developed on a 32-node CM5 running CMOST v7.2 and
***************
*** 266,333 ****
  
  BUGS
  
! 	1. The function pvm_kill() does not behave like a Unix kill: it
  will delete the target task from PVM's task queue but doesn't actually
  kill the task. 
  
! 	2. Signals sent by pvm_sendsig() are simply discarded, except for
  SIGTERM and SIGKILL, which are equivalent to calling pvm_kill().
  
! 	3. You're not allowed to spawn more tasks than the number of nodes
  available in your partition in one call to pvm_spawn().
  
! 	4. If you kill the node tasks from PVM (e.g., using pvm_kill), the
  node processes will dump core files into your HOME directory. I don't
  consider this to be a PVM bug.
  
  
  
  5. Shared-memory Systems
  ------------------------
  
! 	These ports achieve better performance by placing the message buffers
! in shared-memory. Tasks on the same host exchange messages by mapping
! each other's buffers into their own address space.
  
  
! BUGS
  
! 	1. Messages are sent directly, there is no need to call
! pvm_setopt(PvmRoute, PvmRouteDirect). The sender will block if the
! receiving box is full. It will also block if its own outgoing message 
! buffer is full. This could lead to deadlocks.
  
! 	2. The buffer size used by PVM, SHMBUFSIZE, is defined in 
! pvm3/src/pvmshmem.h, with a default of 1MBytes. Your message must fit
! in the buffer. If your program uses large messages, this parameter MUST
! be increased accordingly. Note that the default system limit on shared-
! memory segment size (1 MB on Sun's) may have to be raised as well.
! A large number of small messages can also fill up the buffer if they
! are not received in time, and the performance degrades considerably
! when this happens. 
  
! 	3. You can change the buffer size by setting the environment
! variable PVMBUFSIZE before starting PVM. This would have the same
! effect as changing SHMBUFSIZE and recompiling PVM.
  
! 	4. When a task sends a message to another task, only the pointer
! is passed. The receiving task should call pvm_freebuf() to "destroy"
! the receive buffer after the data have been unpacked, and allow the
! sender to reuse that space.
  
! 	5. If you save any PVM buffers (with pvm_setsbuf, for example), 
! it is important that you free them before calling pvm_exit(), otherwise
! your process will hang.
  
- 	6. The socket-based library has been renamed libpvm3s.a; PVM (more
- precisely, the daemon) can serve tasks compiled with either library.
- If you want to use sockets in your application compile it with the
- option "-lpvm3s". Tasks using different libraries can (only) communicate 
- through pvmd (i.e. no PvmRouteDirect).
  
! 	7. DataInPlace encoding not supported in this release.
! 
! Solaris2.3
  ----------
  
  APPLICATION PROGRAMS
--- 344,465 ----
  
  BUGS
  
! 	a) The function pvm_kill() does not behave like a Unix kill: it
  will delete the target task from PVM's task queue but doesn't actually
  kill the task. 
  
! 	b) Signals sent by pvm_sendsig() are simply discarded, except for
  SIGTERM and SIGKILL, which are equivalent to calling pvm_kill().
  
! 	c) You're not allowed to spawn more tasks than the number of nodes
  available in your partition in one call to pvm_spawn().
  
! 	d) If you kill the node tasks from PVM (e.g., using pvm_kill), the
  node processes will dump core files into your HOME directory. I don't
  consider this to be a PVM bug.
  
  
  
+ 6. IBM SP2
+ ----------
+ 
+ 	This implementation is built on top of MPI-F, IBM's version of the
+ Message Passing Interface. Information provided by Hubertus Franke of
+ IBM T. J. Watson Research Center is gratefully acknowledged.
+ 
+ 
+ INSTALLATION
+ 
+ 	Type "make PVM_ARCH=SP2MPI" in this directory. Make sure the mpicc
+ compiler is in your path.
+ 
+ 	To make the examples, go to the "examples" directory, and type
+ 		setenv PVM_ARCH SP2MPI; ../lib/aimk
+ 
+ 
+ APPLICATION PROGRAMS
+ 
+ 	Host (master) programs should be linked with pvm3/lib/SP2MPI/libpvm3.a .
+ Node (slave) programs must be compiled with the mpicc compiler for a C
+ program and mpixlf compiler for a FORTRAN program, and then linked with
+ pvm3/lib/SP2MPI/libpvm3pe.a . FORTRAN programs should also be linked with 
+ pvm3/lib/SP2MPI/libfpvm3.a .
+ 
+ 	The programs in the gexamples directory have NOT been ported. The
+ user must modify the makefiles to link to the appropriate libraries.
+ 
+ 
+ BUGS AND CAVEATS
+ 
+ 	a) The user is required to provide a node file for the SP2 that lists
+ all the nodes the user intends to run PVM on. This is not to be confused 
+ with the PVM hostfile. Before starting PVM, the POE environment variable
+ MP_HOSTFILE should be set to the path of the user's SP2 node file. For
+ example I have the line "setenv MP_HOSTFILE ~/host.list" in my .cshrc file.
+ My host.list file contains the names of the high-performance switches on 
+ all the parallel nodes.
+ 
+ 	b) On a SP2 node only one process can use the switch at any given time. 
+ To run your program you need one node for each PVM task, plus one for the 
+ PVM host process that relays messages for pvmd. So if you want to spawn 8 
+ PVM tasks, for instance, you'll need at least 9 node names in your SP2 
+ node file. Remember there is a host process for each group of tasks spawned
+ together. If you spawn 8 tasks in two batches, you'll need 10 nodes instead
+ of 9.
+ 
+ 	c) Signals sent by pvm_sendsig() are simply discarded, except for
+ SIGTERM and SIGKILL, which are equivalent to calling pvm_kill().
+ 
+ 	d) If you kill one PVM task using pvm_kill(), all the tasks spawned
+ together will also die in sympathy.
+ 
+ 	e) To get the best performance for communications that involves pvmd,
+ for example when you pass messages between two group of tasks spawned
+ separately, use switch names in the node file instead of the host names,
+ and start pvm with the -nswitchname option. This would force any socket
+ communication to go over the high-performance switch rather than Ethernet.
+ 
+ 
+ 
  5. Shared-memory Systems
  ------------------------
  
! 	These ports achieve better performance by using shared memory instead
! of sockets to pass messages. They're fully compatible with the socket
! version. The original socket library has been renamed libpvm3s.a, users
! can link their programs with -lpvm3s if they would rather use sockets
! than shared memory. In addition, tasks linked to different PVM libraries
! can coexist and communicate with each other. (These messages have to be
! routed by the PVM daemon.)
  
  
! BUGS AND CAVEATS
  
! 	a) Messages are sent directly, pvm_setopt(PvmRoute, PvmRouteDirect)
! has no effect. The sender will block if the receiving buffer is full. This 
! could lead to deadlocks.
  
! 	b) The buffer size used by PVM, SHMBUFSIZE, is defined in 
! pvm3/src/pvmshmem.h, with a default of 1MBytes. You can change the buffer 
! size by setting the environment variable PVMBUFSIZE before starting PVM.
! Note that the default system limit on shared-memory segment size (1 MB on
! Sun's) may have to be raised as well.
  
!     c) PVM uses the last 10 bits of the Unix user ID as the base for the
! shared-memory keys. If there is a conflict with keys used by another user
! or application, you can set the environment variable PVMSHMIDBASE to a
! different value.
  
!     d) If PVM crashes for any reason, you may have to remove the leftover
! shared-memory segments and/or semaphores manually. Use the Uhix command
! `ipcs` to list them and `ipcrm` to delete them.  Or, use the script
! `ipcfree` in $PVM_ROOT/lib.
  
!     e) For best performance, use psend/precv. If you must use the standard
! send/recv, the InPlace encoding should be used where appropiate.
  
  
! Solaris2.4
  ----------
  
  APPLICATION PROGRAMS
***************
*** 336,348 ****
  Refer to the example Makefile (pvm3/examples/SUNMP/Makefile) for 
  details.
  
  
! BUGS
! 
! 	1. This software has been tested on a 2-processor Sparc10/512, a
! 4-processor SparcServer1000, and a 24-processor Cray CS6400. 
! 
! 	2. There is a system limit on the number of shared-memory segments
  a process can attach to. This in turn imposes a limit on the number of
  PVM tasks allowed on a single host. According to Sun Microsystem, the
  system parameter can be set by a system administrator:
--- 468,476 ----
  Refer to the example Makefile (pvm3/examples/SUNMP/Makefile) for 
  details.
  
+ BUGS AND CAVEATS
  
! 	a) There is a system limit on the number of shared-memory segments
  a process can attach to. This in turn imposes a limit on the number of
  PVM tasks allowed on a single host. According to Sun Microsystem, the
  system parameter can be set by a system administrator:
***************
*** 365,375 ****
  The default seems to be six but for tpc we up it in "/etc/system".
  =======================================================================
  
- 	3. Occasionally dead PVM processes can become zombies and haunt
- the daemon. When this happens the pvmd3 process must be killed manually
- (with kill -9).
  
- 
  SGI 5.1.1.2
  -----------
  
--- 493,499 ----
***************
*** 380,447 ****
  (pvm3/examples/SGIMP/Makefile) for details.
  
  
- BUGS
- 
- 	1. This software has only been tested on a 2-way SGI Power system.
- 
- 
- 
- 6. IBM SP2
- ----------
- 
- 	This implementation is built on top of MPI-F, IBM's version of the
- Message Passing Interface. Information provided by Hubertus Franke of
- IBM T. J. Watson Research Center is gratefully acknowledged.
- 
- 
- INSTALLATION
- 
- 	Type "make PVM_ARCH=SP2MPI" in this directory. Make sure the mpicc
- compiler is in your path.
- 
- 	To make the examples, go to the "examples" directory, and type
- 		setenv PVM_ARCH SP2MPI; ../lib/aimk
- 
- 
- APPLICATION PROGRAMS
- 
- 	Host (master) programs should be linked with pvm3/lib/SP2MPI/libpvm3.a .
- Node (slave) programs must be compiled with the mpicc compiler for a C
- program and mpixlf compiler for a FORTRAN program, and then linked with
- pvm3/lib/SP2MPI/libpvm3pe.a . FORTRAN programs should also be linked with 
- pvm3/lib/SP2MPI/libfpvm3.a .
- 
- 	The programs in the gexamples directory have NOT been ported. The
- user must modify the makefiles to link to the appropriate libraries.
- 
- 
  BUGS AND CAVEATS
  
! 	1. The user is required to provide a node file for the SP2 that lists
! all the nodes the user intends to run PVM on. This is not to be confused 
! with the PVM hostfile. Before starting PVM, the POE environment variable
! MP_HOSTFILE should be set to the path of the user's SP2 node file. For
! example I have the line "setenv MP_HOSTFILE ~/host.list" in my .cshrc file.
! My host.list file contains the names of the switches on all the parallel
! nodes.
  
! 	2. On a SP2 node only one process can use the switch at any given time. 
! To run your program you need one node for each PVM task, plus one for the 
! PVM host process that relays messages for pvmd. So if you want to spawn 8 
! PVM tasks, for instance, you'll need at least 9 node names in your SP2 
! node file. Remember there is a host process for each group of tasks spawned
! together. If you spawn 8 tasks in two batches, you'll need 10 nodes instead
! of 9.
! 
! 	3. Signals sent by pvm_sendsig() are simply discarded, except for
! SIGTERM and SIGKILL, which are equivalent to calling pvm_kill().
! 
! 	4. If you kill one PVM task using pvm_kill(), all the tasks spawned
! together will also die in sympathy.
! 
! 	5. To get the best performance for communications that involves pvmd,
! for example when you pass messages between two group of tasks spawned
! separately, use switch names in the node file instead of the host names,
! and start pvm with the -nswitchname option. This would force any socket
! communication to go over the high-performance switch rather than Ethernet.
! 
--- 504,512 ----
  (pvm3/examples/SGIMP/Makefile) for details.
  
  
  BUGS AND CAVEATS
  
! 	a) The PVM group does not have access to a multiprocessor SGI machine.
! You're on your own.
  
!     b) There is a system limit on the number of semaphores.
*** /dev/null	Fri Nov 10 16:54:32 1995
--- conf/ATT.def	Tue Oct 31 01:14:43 1995
***************
*** 0 ****
--- 1,6 ----
+ ARCHCFLAGS	=	-DHASSTDLIB -DNOUNIXDOM -DNOGETDTBLSIZ -DNOWAIT3 -DRSHCOMMAND=\"/usr/bin/remsh\" -DSYSVBFUNC -DSYSVSIGNAL -DSYSVSTR -DNEEDSENDIAN
+ ARCHDLIB	=	-lnsl -lsocket -L/usr/ucblib -lucb
+ ARCHDOBJ	=
+ ARCHLIB	=	-lnsl -lsocket -L/usr/ucblib -lucb
+ HASRANLIB	=	f
+ PVM_ARCH	=	ATT
*** /dev/null	Fri Nov 10 16:54:32 1995
--- conf/ATT.m4	Tue Oct 31 01:14:43 1995
***************
*** 0 ****
--- 1,19 ----
+ divert(-1)
+ undefine(`len')
+ #
+ # append an underscore to FORTRAN function names
+ #
+ define(`FUNCTION',`$1_')
+ #
+ # FORTRAN character strings are passed as follows:
+ # a pointer to the base of the string is passed in the normal
+ # argument list, and the length is passed by value as an extra
+ # argument, after all of the other arguments.
+ #
+ define(`ARGS',`($1`'undivert(1))')
+ define(`SAVE',`divert(1)$1`'divert(0)')
+ define(`STRING_ARG',`$1_ptr`'SAVE(`, $1_len')')
+ define(`STRING_ARG_DECL',`char * $1_ptr; int $1_len')
+ define(`STRING_LEN',`$1_len')
+ define(`STRING_PTR',`$1_ptr')
+ divert(0)
*** ../netlib/pvm3.3.9/conf/CUBE.def	Sat Jun  4 17:52:04 1994
--- conf/CUBE.def	Tue Oct 31 01:14:43 1995
***************
*** 1,4 ****
! ARCHCFLAGS	=	-DSYSVSTR -DI860_NODE -DSYSVBFUNC -DNOUNIXDOM
  ARCHDLIB	=
  ARCHDOBJ	=
  ARCHLIB		=
--- 1,4 ----
! ARCHCFLAGS	=	-DSYSVSTR -DI860_NODE -DSYSVBFUNC -DNOUNIXDOM -DNEEDSFFS
  ARCHDLIB	=
  ARCHDOBJ	=
  ARCHLIB		=
*** ../netlib/pvm3.3.9/conf/E88K.def	Sat Jun  4 17:52:04 1994
--- conf/E88K.def	Tue Oct 31 01:14:43 1995
***************
*** 1,4 ****
! ARCHCFLAGS	= -DNOUNIXDOM
  ARCHDLIB	=
  ARCHDOBJ	=
  ARCHLIB	=	-lrpc
--- 1,4 ----
! ARCHCFLAGS	= -DNOUNIXDOM -DNET_IF_IN_SYS
  ARCHDLIB	=
  ARCHDOBJ	=
  ARCHLIB	=	-lrpc
*** ../netlib/pvm3.3.9/conf/FREEBSD.def	Fri Jul 28 12:10:36 1995
--- conf/FREEBSD.def	Tue Oct 31 01:14:44 1995
***************
*** 1,4 ****
! ARCHCFLAGS	=	-DSOCKADHASLEN -DNOREXEC -DRSHCOMMAND=\"/usr/bin/rsh\" -DHASSTDLIB -DNEEDMENDIAN
  ARCHDLIB	=
  ARCHDOBJ	=
  ARCHLIB	=	-lrpcsvc
--- 1,4 ----
! ARCHCFLAGS	=	-DSOCKADHASLEN -DNOREXEC -DRSHCOMMAND=\"/usr/bin/rsh\" -DHASSTDLIB -DNEEDMENDIAN -DHASERRORVARS -DFAKEXDRFLOAT
  ARCHDLIB	=
  ARCHDOBJ	=
  ARCHLIB	=	-lrpcsvc
*** ../netlib/pvm3.3.9/conf/HPPAMP.def	Wed May 24 15:11:41 1995
--- conf/HPPAMP.def	Thu Nov  9 15:37:52 1995
***************
*** 1,4 ****
! ARCHCFLAGS	=	-DSYSVSIGNAL -DNOWAIT3 -DNOGETDTBLSIZ -DRSHCOMMAND=\"/usr/bin/remsh\" -DFDSETISINT
  ARCHDLIB	=
  ARCHDOBJ	=
  ARCHLIB	=
--- 1,4 ----
! ARCHCFLAGS	=	-DSHMEM -DSYSVSIGNAL -DNOWAIT3 -DNOGETDTBLSIZ -DRSHCOMMAND=\"/usr/bin/remsh\" -DNOUNIXDOM -DCLUMP_ALLOC -DHASSTDLIB -DFDSETISINT
  ARCHDLIB	=
  ARCHDOBJ	=
  ARCHLIB	=
*** ../netlib/pvm3.3.9/conf/RS6K.def	Tue Dec 20 11:19:35 1994
--- conf/RS6K.def	Tue Oct 31 01:14:44 1995
***************
*** 1,4 ****
! ARCHCFLAGS	=	-DSYSVSIGNAL
  ARCHDLIB	=	-lbsd
  ARCHDOBJ	=
  ARCHLIB	=
--- 1,4 ----
! ARCHCFLAGS	=	-DSYSVSIGNAL -DRSHCOMMAND=\"/usr/bin/rsh\"
  ARCHDLIB	=	-lbsd
  ARCHDOBJ	=
  ARCHLIB	=
*** ../netlib/pvm3.3.9/conf/RS6KMP.def	Mon May 22 15:28:53 1995
--- conf/RS6KMP.def	Tue Oct 31 01:14:44 1995
***************
*** 1,4 ****
! ARCHCFLAGS	=	-DSYSVSIGNAL -DNOUNIXDOM -D_BSD
  ARCHDLIB	=	-lbsd -lpthreads
  ARCHDOBJ	=
  ARCHLIB		=	-lbsd -lpthreads 
--- 1,4 ----
! ARCHCFLAGS	=	-DSYSVSIGNAL -DNOUNIXDOM -D_BSD -DRSHCOMMAND=\"/usr/bin/rsh\"
  ARCHDLIB	=	-lbsd -lpthreads
  ARCHDOBJ	=
  ARCHLIB		=	-lbsd -lpthreads 
*** ../netlib/pvm3.3.9/conf/SCO.def	Mon Oct 24 16:26:00 1994
--- conf/SCO.def	Tue Oct 31 01:14:44 1995
***************
*** 1,4 ****
! ARCHCFLAGS	=	 -DSYSVSTR -DSYSVSIGNAL -D__SCO_WAIT3__ -DNOUNIXDOM -DRSHCOMMAND=\"/usr/bin/rsh\"
  ARCHDLIB	=	-lsocket
  ARCHDOBJ	=
  ARCHLIB	=	-lrpc -lsocket
--- 1,4 ----
! ARCHCFLAGS	=	 -DSYSVSTR -DSYSVSIGNAL -D__SCO_WAIT3__ -DNOUNIXDOM -DRSHCOMMAND=\"/usr/bin/rsh\" -DNEEDSFFS
  ARCHDLIB	=	-lsocket
  ARCHDOBJ	=
  ARCHLIB	=	-lrpc -lsocket
*** ../netlib/pvm3.3.9/conf/SUN4SOL2.def	Sat Jun  4 17:52:08 1994
--- conf/SUN4SOL2.def	Tue Oct 31 01:14:44 1995
***************
*** 1,4 ****
! ARCHCFLAGS	=	-DSYSVBFUNC -DSYSVSTR -DNOGETDTBLSIZ -DSYSVSIGNAL -DNOWAIT3 -DNOUNIXDOM
  ARCHDLIB	=	-lnsl -lsocket
  ARCHDOBJ	=
  ARCHLIB	=	-lnsl -lsocket
--- 1,4 ----
! ARCHCFLAGS	=	-DSYSVBFUNC -DSYSVSTR -DNOGETDTBLSIZ -DSYSVSIGNAL -DNOWAIT3 -DNOUNIXDOM -DRSHCOMMAND=\"/usr/bin/rsh\"
  ARCHDLIB	=	-lnsl -lsocket
  ARCHDOBJ	=
  ARCHLIB	=	-lnsl -lsocket
*** ../netlib/pvm3.3.9/conf/SUNMP.def	Mon Jul 10 12:43:40 1995
--- conf/SUNMP.def	Thu Nov  2 10:09:31 1995
***************
*** 1,4 ****
! ARCHCFLAGS	=	-DSYSVBFUNC -DSYSVSTR -DNOGETDTBLSIZ -DSYSVSIGNAL -DNOWAIT3 -DNOUNIXDOM
  ARCHDLIB	=	-lnsl -lsocket -lthread
  ARCHDOBJ	=
  ARCHLIB	=	-lnsl -lsocket -lthread
--- 1,4 ----
! ARCHCFLAGS	=	-DSYSVBFUNC -DSYSVSTR -DNOGETDTBLSIZ -DSYSVSIGNAL -DNOWAIT3 -DNOUNIXDOM -DRSHCOMMAND=\"/usr/bin/rsh\"
  ARCHDLIB	=	-lnsl -lsocket -lthread
  ARCHDOBJ	=
  ARCHLIB	=	-lnsl -lsocket -lthread
*** ../netlib/pvm3.3.9/conf/TITN.def	Sat Jun  4 17:52:08 1994
--- conf/TITN.def	Tue Oct 31 01:14:44 1995
***************
*** 1,4 ****
! ARCHCFLAGS	=	-DNOGETDTBLSIZ -DSYSVSIGNAL -DNOWAIT3 -DSYSVSTR -DNOREXEC -DNOSOCKOPT -DNOUNIXDOM
  ARCHDLIB	=
  ARCHDOBJ	=
  ARCHLIB	=
--- 1,4 ----
! ARCHCFLAGS	=	-DNOGETDTBLSIZ -DSYSVSIGNAL -DNOWAIT3 -DSYSVSTR -DNOREXEC -DNOSOCKOPT -DNOUNIXDOM -DNEEDSFFS
  ARCHDLIB	=
  ARCHDOBJ	=
  ARCHLIB	=
*** ../netlib/pvm3.3.9/conf/UTS2.def	Fri Jul 28 12:46:54 1995
--- conf/UTS2.def	Tue Oct 31 01:14:45 1995
***************
*** 1,4 ****
! ARCHCFLAGS    =       -eft -DSYSVSTR -DNOUNIXDOM
  ARCHDLIB      =       -lnsl -lsocket -lbsd -lrpc
  ARCHLIB               =       -lnsl -lsocket -lbsd -lrpc
  ARCHDOBJS     =
--- 1,4 ----
! ARCHCFLAGS    =       -eft -DSYSVSTR -DNOUNIXDOM -DNET_IF_IN_SYS
  ARCHDLIB      =       -lnsl -lsocket -lbsd -lrpc
  ARCHLIB               =       -lnsl -lsocket -lbsd -lrpc
  ARCHDOBJS     =
*** /dev/null	Fri Nov 10 16:54:51 1995
--- conf/X86SOL2.def	Tue Oct 31 01:14:45 1995
***************
*** 0 ****
--- 1,6 ----
+ ARCHCFLAGS	=	-DSYSVBFUNC -DSYSVSTR -DNOGETDTBLSIZ -DSYSVSIGNAL -DNOWAIT3 -DNOUNIXDOM -DRSHCOMMAND=\"/usr/bin/rsh\"
+ ARCHDLIB	=	-lnsl -lsocket
+ ARCHDOBJ	=
+ ARCHLIB	=	-lnsl -lsocket
+ HASRANLIB	=	f
+ PVM_ARCH	=	X86SOL2
*** /dev/null	Fri Nov 10 16:54:51 1995
--- conf/X86SOL2.m4	Tue Oct 31 01:14:45 1995
***************
*** 0 ****
--- 1,19 ----
+ divert(-1)
+ undefine(`len')
+ #
+ # append an underscore to FORTRAN function names
+ #
+ define(`FUNCTION',`$1_')
+ #
+ # FORTRAN character strings are passed as follows:
+ # a pointer to the base of the string is passed in the normal
+ # argument list, and the length is passed by value as an extra
+ # argument, after all of the other arguments.
+ #
+ define(`ARGS',`($1`'undivert(1))')
+ define(`SAVE',`divert(1)$1`'divert(0)')
+ define(`STRING_ARG',`$1_ptr`'SAVE(`, $1_len')')
+ define(`STRING_ARG_DECL',`char * $1_ptr; int $1_len')
+ define(`STRING_LEN',`$1_len')
+ define(`STRING_PTR',`$1_ptr')
+ divert(0)
*** ../netlib/pvm3.3.9/console/cmds.c	Fri Sep  8 13:58:55 1995
--- console/cmds.c	Thu Nov  2 10:11:47 1995
***************
*** 32,37 ****
--- 32,40 ----
   *	PVM console commands.
   *
  $Log: cmds.c,v $
+  * Revision 1.8  1995/11/02  15:11:40  manchek
+  * added to tickle help
+  *
   * Revision 1.7  1995/09/05  19:06:52  manchek
   * help text lowercase
   *
***************
*** 153,159 ****
  	{ 0, 0, 0, 0 }
  };
  
! static char rcsid[] = "$Id: cmds.c,v 1.7 1995/09/05 19:06:52 manchek Exp $";
  
  
  freealias(ap)
--- 156,162 ----
  	{ 0, 0, 0, 0 }
  };
  
! static char rcsid[] = "$Id: cmds.c,v 1.8 1995/11/02 15:11:40 manchek Exp $";
  
  
  freealias(ap)
***************
*** 534,539 ****
--- 537,557 ----
  	"tickle-  4   dump class-name list",
  	"tickle-  5   get debugmask",
  	"tickle-  6   (mask) set debugmask",
+ 	"tickle-        mask is the sum of the following bits for information about",
+ 	"tickle-           1  Packet routing",
+ 	"tickle-           2  Message routing and entry points",
+ 	"tickle-           4  Task state",
+ 	"tickle-           8  Slave pvmd startup",
+ 	"tickle-          16  Host table updates",
+ 	"tickle-          32  Select loop",
+ 	"tickle-          64  IP network",
+ 	"tickle-         128  Multiprocessor nodes",
+ 	"tickle-         256  Resource manager interface",
+ 	"tickle-         512  Application warnings (scrapped messages etc.)",
+ 	"tickle-        1024  Wait contexts",
+ 	"tickle-        2048  Shared memory operations",
+ 	"tickle-        4096  Semaphores",
+ 	"tickle-        8192  Locks",
  	"tickle-  7   (num) set nopax",
  	"tickle-  8   (dtid) trigger hostfail",
  	"tickle-  9   (rst) dump pvmd statistics, clear if rst true",
*** ../netlib/pvm3.3.9/doc/bugreport	Fri Jun  2 12:25:14 1995
--- doc/bugreport	Thu Nov  2 10:21:37 1995
***************
*** 10,24 ****
  ________________________________________________________________________
  Please try to include the following information:
  
! * The exact version, patch level you're using (e.g. 3.3.0).
  
  * The machine type(s) you're using, hardware and software (e.g. DEC
!   3000/500 running OSF 1.2).
  
  * The machine architecture PVM chooses for you (e.g. ALPHA).
  
! * A short description of the problem (what happens, when, etc.).
!   Include error messages (don't edit them to summarize).
  
! * A record of what you did to make it happen.
  
--- 10,33 ----
  ________________________________________________________________________
  Please try to include the following information:
  
! * The exact version and patch level of PVM you're using (e.g. 3.3.10).
!   This is necessary, because we don't want to go looking through source
!   for all past versions of PVM.  Also, if you're using an old version,
!   you mave have found a bug that we've already fixed.
  
  * The machine type(s) you're using, hardware and software (e.g. DEC
!   3000/500 running OSF 1.2).  This is helpful if we want to try to
!   reproduce the bug here.  Also, we know very little about some of the
!   machines PVM runs on and we'll be able to tell you that.
  
  * The machine architecture PVM chooses for you (e.g. ALPHA).
  
! * A short description of the problem (what happens, when it happens,
!   what you did, etc.).  Include any relevant input you typed and output
!   printed by PVM.  Don't edit the output to format it or summarize it
!   (except maybe for removing 10000 lines that say the same thing - make
!   a note you did this).  Crucial information about the bug may be in a
!   few numbers or words.
  
! * Please warn us if you've made any changes to the distribution source.
  
*** ../netlib/pvm3.3.9/lib/debugger	Thu Aug 19 17:25:23 1993
--- lib/debugger	Thu Nov  2 11:47:22 1995
***************
*** 15,20 ****
  endif
  
  set noglob
! set hn=`hostname`
  exec xterm -title "${hn}:$argv[1]" -e $PVM_ROOT/lib/debugger2 $argv
  
--- 15,24 ----
  endif
  
  set noglob
! if ($PVM_ARCH == "SUN4SOL2" || $PVM_ARCH == "SUNMP" || $PVM_ARCH == "X86SOL2") then
! 	set hn=`uname -n`
! else
! 	set hn=`hostname`
! endif
  exec xterm -title "${hn}:$argv[1]" -e $PVM_ROOT/lib/debugger2 $argv
  
*** /dev/null	Fri Nov 10 16:55:10 1995
--- lib/ipcfree	Thu Nov  2 11:43:54 1995
***************
*** 0 ****
--- 1,28 ----
+ #!/bin/sh
+ #
+ # ipcfree
+ #
+ # Delete any shared memory or semaphores lying around after a PVM
+ # program bombs out or is killed ungracefully.
+ # Run it if you're getting error messages like:
+ #   semget: ... No space left on device
+ #   shmget: ... No space left on device
+ # when using one of the *MP PVM architectures.
+ #
+ 
+ if [ "$USER" = "" ]; then
+ 	USER=` whoami `
+ fi
+ 
+ m=` ipcs | awk '$1~/^[ms]$/ && $5~/'$USER'/ {print "-"$1, $2}' `
+ 
+ case "$m" in
+ ?*) echo "deleting $m"
+     ipcrm $m
+ ;;
+ *) echo "didn't find anything"
+ ;;
+ esac
+ 
+ exit 0
+ 
*** ../netlib/pvm3.3.9/lib/pvmgetarch	Fri Sep  8 13:58:57 1995
--- lib/pvmgetarch	Thu Nov  2 10:37:18 1995
***************
*** 23,28 ****
--- 23,31 ----
  #
  ARCH=UNKNOWN
  
+ #
+ # determine the machine type from scratch
+ #
  if [ -f /bin/uname -o -f /usr/bin/uname ]; then
  	if [ -f /bin/uname ]; then
  		os="`/bin/uname -s`"
***************
*** 35,40 ****
--- 38,44 ----
  	case "$os,$ht" in
  	SunOS,sun3* )           ARCH=SUN3 ;;
  	SunOS,sun4* )           ARCH=SUN4 ;;
+ 	SunOS,i86pc )           ARCH=X86SOL2 ;;
  	ULTRIX,RISC )           ARCH=PMAX ;;
  	ULTRIX,VAX )            ARCH=UVAX ;;
  	AIX*,* )                ARCH=RS6K ;;
***************
*** 69,74 ****
--- 73,80 ----
  
  if [ "$ARCH" = UNKNOWN ]; then
  
+ 	if [ -f /usr/etc/RELDEF ]; then ARCH=ATT; fi
+ 
  	if [ -f /ultrixboot ]; then
  		if [ -f /pcs750.bin ]; then
  			ARCH=UVAX
***************
*** 128,133 ****
--- 134,142 ----
  	fi
  fi
  
+ #
+ # update the machine type to derive subclasses
+ #
  if [ "$ARCH" = SUN4 ]; then
  	rel="`/bin/uname -r`"
  	case "$rel" in
***************
*** 170,177 ****
  fi
  if [ "$ARCH" = PMAX -a -d /usr/maspar ]; then ARCH=MASPAR; fi
  if [ "$ARCH" = RS6K ]; then 
! 	nproc="`/usr/sbin/lsdev -C | grep proc | wc -l`"
! 	if [ $nproc -gt 2 ]; then ARCH=RS6KMP; fi
  fi
  if [ "$ARCH" = HPPA -a -f /bin/sysinfo ]; then ARCH=CSPP; fi
  
--- 179,186 ----
  fi
  if [ "$ARCH" = PMAX -a -d /usr/maspar ]; then ARCH=MASPAR; fi
  if [ "$ARCH" = RS6K ]; then 
! 	nproc="`/usr/sbin/lsdev -C -c processor | wc -l`"
! 	if [ $nproc -gt 1 ]; then ARCH=RS6KMP; fi
  fi
  if [ "$ARCH" = HPPA -a -f /bin/sysinfo ]; then ARCH=CSPP; fi
  
*** ../netlib/pvm3.3.9/man/man1/pvm_intro.1	Fri Sep  8 13:58:57 1995
--- man/man1/pvm_intro.1	Thu Nov  2 12:01:19 1995
***************
*** 33,38 ****
--- 33,41 ----
  ALPHAMP
  DEC Alpha/OSF-1 / using shared memory
  .TP
+ ATT
+ AT&T/NCR 3600 running SysVR4
+ .TP
  BAL
  Sequent Balance
  .TP
***************
*** 192,202 ****
  UVAX
  DEC/Microvax
  .TP
  VCM2
  Thinking Machines CM-2 Vax front-end
  .TP
! UXPM
! Fujitsu running UXP/M
  .PD
  .RE
  .\".SH INSTALLING
--- 195,208 ----
  UVAX
  DEC/Microvax
  .TP
+ UXPM
+ Fujitsu running UXP/M
+ .TP
  VCM2
  Thinking Machines CM-2 Vax front-end
  .TP
! X86SOL2
! 80[345]86 running Solaris 2.x
  .PD
  .RE
  .\".SH INSTALLING
*** ../netlib/pvm3.3.9/man/man1/pvmd3.1	Thu May 11 16:07:54 1995
--- man/man1/pvmd3.1	Tue Oct 31 01:14:48 1995
***************
*** 49,55 ****
  Message routing and entry points
  .TP
  4
! Task management
  .TP
  8
  Slave pvmd startup
--- 49,55 ----
  Message routing and entry points
  .TP
  4
! Task state
  .TP
  8
  Slave pvmd startup
***************
*** 64,70 ****
  IP network
  .TP
  80
! Multiprocessor port debugging
  .TP
  100
  Resource manager interface
--- 64,70 ----
  IP network
  .TP
  80
! Multiprocessor nodes
  .TP
  100
  Resource manager interface
***************
*** 73,79 ****
  Application (messages with no destination, etc.)
  .TP
  400
! Shared memory transport debugging
  .TP
  800
  Semaphores
--- 73,79 ----
  Application (messages with no destination, etc.)
  .TP
  400
! Shared memory operations
  .TP
  800
  Semaphores
*** /dev/null	Fri Nov 10 16:55:31 1995
--- misc/README	Thu Nov  2 11:44:10 1995
***************
*** 0 ****
--- 1,34 ----
+ 
+ misc directory
+ 09 October 1995
+ 
+ ________________________________________________________________________
+ 
+ This directory contains a bunch of random PVM-related programs and
+ utilities.  They're here because they might be generally useful, but
+ I don't want to kill myself supporting them.  Like the "examples",
+ even less official.
+ 
+ pvm_fork.c
+ 
+  This is an implementation of pvm_fork(), a function to fork a new PVM
+  task from an existing PVM task.
+ 
+ xhoster/
+ 
+  This is a little X-Windows program that enrolls as the hoster task,
+  giving the user a convenient place to type passwords when starting
+  hosts that require them.
+ 
+ group-hack-337
+ 
+  This is a patch to PVM version 3.3.7 to allow access to the virtual
+  machine to anyone in a unix group.  If environment variable PVM_GID
+  is set to the name or number of a group, sockets and files are
+  chown'd to that group and mode 0660 is used instead of 0600.
+ 
+  Note that all spawned processes have the same user id as the pvmd,
+  so this isn't a true multi-user virtual machine.  This is seen as
+  being useful mainly for allowing e.g. a group of people access to
+  a database, or display or instrument server.
+ 
*** /dev/null	Fri Nov 10 16:55:31 1995
--- misc/group-hack-337	Tue Oct 31 01:14:49 1995
***************
*** 0 ****
--- 1,209 ----
+ *** ../../netlib/pvm3.3.7/src/lpvm.c	Tue Feb 07 15:16:11 1995
+ --- lpvm.c	Mon May 15 14:17:06 1995
+ ***************
+ *** 1971,1976 ****
+ --- 1971,1977 ----
+   	char buf[16];					/* for converting sockaddr */
+   	char *p;
+   	int x;
+ + 	int gid;
+   
+   /*
+   	pvm_setopt(PvmDebugMask, -1);
+ ***************
+ *** 2033,2038 ****
+ --- 2034,2045 ----
+   		pvmlogerror("pvmbeatask() can't creat t-auth file\n");
+   		cc = PvmSysErr;
+   		goto bail2;
+ + 	}
+ + 	if ((gid = pvmgetugid()) != -1) {
+ + 		if (fchown(authfd, -1, gid) == -1)
+ + 			pvmlogperror("pvmbeatask() can't chown t-auth file");
+ + 		if (fchmod(authfd, 0660) == -1)
+ + 			pvmlogperror("pvmbeatask() can't chmod t-auth file");
+   	}
+   
+   	sbf = pvm_setsbuf(pvm_mkbuf(PvmDataFoo));
+ *** ../../netlib/pvm3.3.7/src/pvmcruft.c	Wed Nov 09 10:58:42 1994
+ --- pvmcruft.c	Mon May 15 14:37:16 1995
+ ***************
+ *** 66,71 ****
+ --- 66,72 ----
+   #include <strings.h>
+   #define	CINDEX(s,c)	index(s,c)
+   #endif
+ + #include <grp.h>
+   #include "global.h"
+   #include "protoglarp.h"
+   #include "pvmalloc.h"
+ ***************
+ *** 458,463 ****
+ --- 459,465 ----
+   
+   	char hna[128];
+   	char *p;
+ + 	int gid;
+   
+   #ifdef	SHAREDTMP
+   	if (gethostname(hna, sizeof(hna)-1) == -1) {
+ ***************
+ *** 466,477 ****
+   	}
+   	if (p = CINDEX(hna, '.'))
+   		*p = 0;
+ ! 	(void)sprintf(buf, TDSOCKNAME, pvm_useruid, hna);
+   
+   #else
+ ! 	(void)sprintf(buf, TDSOCKNAME, pvm_useruid);
+   #endif
+   
+   	return buf;
+   }
+   
+ --- 468,515 ----
+   	}
+   	if (p = CINDEX(hna, '.'))
+   		*p = 0;
+ ! 	if ((gid = pvmgetugid()) != -1) {
+ ! 		(void)sprintf(buf, TDSOCKGNAME, gid, hna);
+ ! 	else
+ ! 		(void)sprintf(buf, TDSOCKNAME, pvm_useruid, hna);
+   
+   #else
+ ! 	if ((gid = pvmgetugid()) != -1)
+ ! 		(void)sprintf(buf, TDSOCKGNAME, gid);
+ ! 	else
+ ! 		(void)sprintf(buf, TDSOCKNAME, pvm_useruid);
+   #endif
+   
+   	return buf;
+   }
+ + 
+ + 
+ + int
+ + pvmgetugid()
+ + {
+ + 	static int gid = -2;
+ + 
+ + 	char *p;
+ + 	struct group *ge;
+ + 	char buf[128];
+ + 
+ + 	if (gid == -2) {
+ + 		gid = -1;
+ + 		if (p = getenv("PVM_GID")) {
+ + 			if (isdigit(*p))
+ + 				return (int)atoi(p);
+ + 
+ + 			if (ge = getgrnam(p))
+ + 				gid = ge->gr_gid;
+ + 			else {
+ + 				sprintf(buf, "pvmgetugid() can't lookup group \"%s\"\n", p);
+ + 				pvmlogerror(buf);
+ + 			}
+ + 			endgrent();
+ + 		}
+ + 	}
+ + 
+ + 	return gid;
+ + }
+ + 
+   
+ *** ../../netlib/pvm3.3.7/src/startup.c	Tue Feb 07 15:16:13 1995
+ --- startup.c	Mon May 15 14:20:43 1995
+ ***************
+ *** 242,247 ****
+ --- 242,248 ----
+   	char spath[LEN_OF_TMP_NAM];	/* local socket path */
+   	struct sockaddr_un uns;
+   #endif
+ + 	int gid;
+   
+   	/*
+   	* make pvmd-pvmd socket
+ ***************
+ *** 395,400 ****
+ --- 396,407 ----
+   		}
+   
+   	} else {
+ + 		if ((gid = pvmgetugid()) != -1) {
+ + 			if (fchown(d, -1, gid) == -1)
+ + 				pvmlogperror("mksocs() can't chown address file");
+ + 			if (fchmod(d, 0640) == -1)
+ + 				pvmlogperror("mksocs() can't chmod address file");
+ + 		}
+   		cc = write(d, p, strlen(p));
+   		if (cc != strlen(p)) {
+   			if (cc == -1) {
+ *** ../../netlib/pvm3.3.7/src/tdpro.c	Wed Nov 09 10:58:44 1994
+ --- tdpro.c	Mon May 15 14:20:54 1995
+ ***************
+ *** 106,111 ****
+ --- 106,113 ----
+    **           **
+    ***************/
+   
+ + char *getenv();
+ + 
+   extern void task_dump();
+   char *debug_flags();
+   char *inadport_hex();
+ ***************
+ *** 298,303 ****
+ --- 300,306 ----
+   	char authfn[LEN_OF_TMP_NAM];	/* t-auth file name */
+   	int d;
+   	int cc;
+ + 	int gid;
+   
+   	if (upkint(mp, &ver) || upkstr(mp, authfn, sizeof(authfn))) {
+   		pvmlogerror("tm_connect() bad msg format\n");
+ ***************
+ *** 345,356 ****
+   	tp->t_authnam = TALLOC(LEN_OF_TMP_NAM, char, "auth");
+   	(void)TMPNAMFUN(tp->t_authnam);
+   
+ ! 	if ((tp->t_authfd = open(tp->t_authnam, O_RDONLY|O_CREAT|O_TRUNC, 0600))
+ ! 	== -1) {
+   		pvmlogperror("tm_connect() can't create d-auth file");
+   		PVM_FREE(tp->t_authnam);
+   		tp->t_authnam = 0;
+   		goto bail;
+   	}
+   
+   	/*
+ --- 348,364 ----
+   	tp->t_authnam = TALLOC(LEN_OF_TMP_NAM, char, "auth");
+   	(void)TMPNAMFUN(tp->t_authnam);
+   
+ ! 	if ((tp->t_authfd = open(tp->t_authnam, O_RDONLY|O_CREAT|O_TRUNC, 0600)) == -1) {
+   		pvmlogperror("tm_connect() can't create d-auth file");
+   		PVM_FREE(tp->t_authnam);
+   		tp->t_authnam = 0;
+   		goto bail;
+ + 	}
+ + 	if ((gid = pvmgetugid()) != -1) {
+ + 		if (fchown(tp->t_authfd, -1, gid) == -1)
+ + 			pvmlogperror("tm_connect() can't chown d-auth file");
+ + 		if (fchmod(tp->t_authfd, 0660) == -1)
+ + 			pvmlogperror("tm_connect() can't chmod d-auth file");
+   	}
+   
+   	/*
+ *** ../../netlib/pvm3.3.7/src/tdpro.h	Fri Jun 03 16:38:32 1994
+ --- tdpro.h	Mon May 15 14:32:25 1995
+ ***************
+ *** 59,66 ****
+ --- 59,68 ----
+   
+   #ifdef	SHAREDTMP
+   #define	TDSOCKNAME	"/tmp/pvmd.%d.%s"	/* file with task->pvmd sockaddr */
+ + #define	TDSOCKGNAME	"/tmp/pvmd.g%d.%s"	/* file with task->pvmd sockaddr */
+   #else
+   #define	TDSOCKNAME	"/tmp/pvmd.%d"	/* file with task->pvmd sockaddr */
+ + #define	TDSOCKGNAME	"/tmp/pvmd.g%d"	/* file with task->pvmd sockaddr */
+   #endif
+   
+   #define	TM_FIRST	0x80010001		/* first TM_ message */
*** /dev/null	Fri Nov 10 16:55:31 1995
--- misc/pvm_fork.c	Tue Oct 31 01:14:53 1995
***************
*** 0 ****
--- 1,57 ----
+ 
+ /*
+ *	pvm_fork.c
+ *
+ *	In the spirit of fork(), fork a process and enroll it as a new PVM task.
+ *	If parent, returns task id (>0) of child, or error (<0).
+ *	If child, returns 0.
+ */
+ 
+ 
+ #ifdef	IMA_TITN
+ #include <sys/socket.h>
+ #endif
+ #include <pvm3.h>
+ 
+ int
+ pvm_fork(cpid)
+ 	int *cpid;		/* cpid returns child pid if nonnull */
+ {
+ 	int tid;		/* tid to return (child tid or 0) */
+ 	int pid;
+ 	int pfd[2];
+ 
+ 	if ((tid = pvm_mytid()) > 0) {
+ 		if (
+ #ifdef	IMA_TITN
+ 		socketpair(AF_UNIX, SOCK_STREAM, 0, pfd)
+ #else
+ 		pipe(pfd)
+ #endif
+ 		== -1)
+ 			tid = PvmOutOfRes;
+ 		else
+ 			if (pid = fork()) {				/* parent */
+ 				close(pfd[1]);
+ 				if (cpid)
+ 					*cpid = pid;
+ 				if (pid == -1)
+ 					tid = PvmOutOfRes;
+ 				else
+ 					if (read(pfd[0], (char *)&tid, sizeof(tid)) != sizeof(tid))
+ 						tid = PvmOutOfRes;
+ 				close(pfd[0]);
+ 
+ 			} else {						/* child */
+ 				close(pfd[0]);
+ 				pvmendtask();
+ 				tid = pvm_mytid();
+ 				write(pfd[1], (char *)&tid, sizeof(tid));
+ 				close(pfd[1]);
+ 				tid = 0;
+ 			}
+ 	}
+ 	return tid;
+ }
+ 
+ 
*** /dev/null	Fri Nov 10 16:55:31 1995
--- misc/xhoster/Imakefile	Tue Oct 31 01:14:54 1995
***************
*** 0 ****
--- 1,10 ----
+ 
+ SRCS = xhoster.c hostc.c
+ OBJS = xhoster.o hostc.o
+ 
+ CCOPTIONS = -I$(PVM_ROOT)/include -DIMA_$(PVM_ARCH) $(ARCHCFLAGS)
+ EXTRA_LOAD_FLAGS = -L$(PVM_ROOT)/lib/$(PVM_ARCH)
+ EXTRA_LIBRARIES = -lXaw -lXt -lXmu -lXext -lX11 -lpvm3
+ 
+ ComplexProgramTarget(xhoster)
+ 
*** /dev/null	Fri Nov 10 16:55:31 1995
--- misc/xhoster/README	Tue Oct 31 01:14:54 1995
***************
*** 0 ****
--- 1,25 ----
+ 
+ Xhoster
+ 09 Oct 1995
+ 
+ ________________________________________________________________________
+ 
+ This is a little X-Windows program that enrolls as the hoster task,
+ giving the user a convenient place to type passwords when starting
+ hosts that require them.  It also logs problems related to startup,
+ for help in debugging.
+ 
+ To build it, type "xmkmf" then "aimk" in this directory, and install
+ it wherever you want, f.e. $PVM_ROOT/lib/$PVM_ARCH/xhoster.
+ 
+ Suggested X defaults to make it look less ugly would be:
+ 
+     xhoster*background: antiquewhite3
+     xhoster*font: -*-helvetica-medium-r-normal--14-100-*-*-p-*-*-*
+     xhoster.geometry: 700x300
+ 
+ The xhoster can be attached and detached without shutting down the
+ pvmds.
+ 
+ -b
+ 
*** /dev/null	Fri Nov 10 16:55:31 1995
--- misc/xhoster/hostc.c	Tue Oct 31 01:14:54 1995
***************
*** 0 ****
--- 1,302 ----
+ 
+ /*
+  *         PVM version 3.3:  Parallel Virtual Machine System
+  *               University of Tennessee, Knoxville TN.
+  *           Oak Ridge National Laboratory, Oak Ridge TN.
+  *                   Emory University, Atlanta GA.
+  *      Authors:  A. L. Beguelin, J. J. Dongarra, G. A. Geist,
+  *    W. C. Jiang, R. J. Manchek, B. K. Moore, and V. S. Sunderam
+  *                   (C) 1992 All Rights Reserved
+  *
+  *                              NOTICE
+  *
+  * Permission to use, copy, modify, and distribute this software and
+  * its documentation for any purpose and without fee is hereby granted
+  * provided that the above copyright notice appear in all copies and
+  * that both the copyright notice and this permission notice appear in
+  * supporting documentation.
+  *
+  * Neither the Institutions (Emory University, Oak Ridge National
+  * Laboratory, and University of Tennessee) nor the Authors make any
+  * representations about the suitability of this software for any
+  * purpose.  This software is provided ``as is'' without express or
+  * implied warranty.
+  *
+  * PVM version 3 was funded in part by the U.S. Department of Energy,
+  * the National Science Foundation and the State of Tennessee.
+  */
+ 
+ /*
+  *	hostc.c
+  *
+  *	Host cache functions.
+  *
+ $Log$
+  */
+ 
+ 
+ #include <stdio.h>
+ #ifdef	SYSVSTR
+ #include <string.h>
+ #else
+ #include <strings.h>
+ #endif
+ #include <sys/types.h>
+ #include <sys/time.h>
+ #ifdef IMA_LINUX
+ #include <linux/time.h>
+ #endif
+ #include <pvm3.h>
+ #include <../src/bfunc.h>
+ #include <../src/listmac.h>
+ #include "myalloc.h"
+ #include "hostc.h"
+ 
+ 
+ static char rcsid[] = "$Id$";
+ static struct hostc *curhosts = 0;
+ static int addtag = -1;
+ static int deltag = -1;
+ static int (*addcallback)() = 0;
+ static int (*delcallback)() = 0;
+ 
+ 
+ static struct hostc *
+ hc_new()
+ {
+ 	struct hostc *hp;
+ 
+ 	if (hp = TALLOC(1, struct hostc, "hd"))
+ 		BZERO(hp, sizeof(struct hostc));
+ 	return hp;
+ }
+ 
+ 
+ static int
+ hc_init()
+ {
+ 	if (curhosts = hc_new())
+ 		curhosts->link = curhosts->rlink = curhosts;
+ 
+ 	else
+ 		fprintf(stderr, "hc_init() out of memory\n");
+ 	return 0;
+ }
+ 
+ 
+ static struct hostc *
+ hc_add(hip)
+ 	struct pvmhostinfo *hip;
+ {
+ 	struct hostc *hp, *hp2;
+ 
+ 	/*
+ 	* if we have a delete message tag and it's not this host, notify
+ 	*/
+ 
+ 	if (deltag != -1 && hip->hi_tid != pvm_tidtohost(pvm_mytid()))
+ 		pvm_notify(PvmHostDelete, deltag, 1, &hip->hi_tid);
+ 
+ 	if (hp = hc_new()) {
+ 		hp->pvmd_tid = hip->hi_tid;
+ 		hp->name = STRALLOC(hip->hi_name);
+ 		hp->alias = STRALLOC(hip->hi_name);
+ 		hp->arch = STRALLOC(hip->hi_arch);
+ 		hp->speed = hip->hi_speed;
+ 		pvm_hostsync(hp->pvmd_tid, (struct timeval *)0, &(hp->delta));
+ 	}
+ 
+ 	for (hp2 = curhosts->link; hp2 != curhosts; hp2 = hp2->link)
+ 		if (hp->pvmd_tid < hp2->pvmd_tid)
+ 			break;
+ 	LISTPUTBEFORE(hp2, hp, link, rlink);
+ 
+ 	return hp;
+ }
+ 
+ 
+ static int
+ hc_delete(hp)
+ 	struct hostc *hp;
+ {
+ 	LISTDELETE(hp, link, rlink);
+ 	if (hp->name)
+ 		MY_FREE(hp->name);
+ 	if (hp->arch)
+ 		MY_FREE(hp->arch);
+ 	if (hp->alias)
+ 		MY_FREE(hp->alias);
+ 	MY_FREE(hp);
+ 	return 0;
+ }
+ 
+ 
+ static struct hostc *
+ hc_find(tid)
+ {
+ 	struct hostc *hp;
+ 
+ 	for (hp = curhosts->link; hp != curhosts; hp = hp->link)
+ 		if (tid <= hp->pvmd_tid)
+ 			break;
+ 	return (tid == hp->pvmd_tid) ? hp : (struct hostc *)0;
+ }
+ 
+ 
+ /*	host_init()
+ *
+ *	Initialize host cache.  Called once at beginning of time.
+ *	Synchronize to current configuration.
+ *	Specify message tags to be used for HostAdd and HostDelete notify.
+ */
+ 
+ host_init(atag, dtag, acb, dcb)
+ 	int atag;			/* message tag to use for HostAdd notify or -1 */
+ 	int dtag;			/* tag to use for HostDelete notify or -1 */
+ 	int (*acb)();		/* callback for each host added */
+ 	int (*dcb)();		/* callback for each host deleted */
+ {
+ 	struct pvmhostinfo *hip;
+ 	int nh;
+ 
+ 	addtag = atag;
+ 	deltag = dtag;
+ 	addcallback = acb;
+ 	delcallback = dcb;
+ 
+ 	hc_init();
+ 
+ 	if (addtag != -1)
+ 		pvm_notify(PvmHostAdd, addtag, -1, (int *)0);
+ 
+ 	if (!pvm_config(&nh, (int *)0, &hip)) {
+ 		while (nh > 0) {
+ 			nh--;
+ 			hc_add(&hip[nh]);
+ 		}
+ 	}
+ 	return 0;
+ }
+ 
+ 
+ /*	host_add()
+ *
+ *	Called when a HostAdd notify message has been received.
+ *	The message is in the current receive buffer.
+ */
+ 
+ host_add()
+ {
+ 	int d = 0;
+ 	int n;
+ 	int *dtids;
+ 	int i, j;
+ 	struct pvmhostinfo *hip;
+ 	int nh;
+ 
+ 	pvm_upkint(&n, 1, 1);
+ 	if (n < 1 || n > 4096)
+ 		return 0;
+ 	dtids = TALLOC(n, int, "dtid");
+ 	pvm_upkint(dtids, n, 1);
+ 	pvm_freebuf(pvm_getrbuf());
+ 	if (!pvm_config(&nh, (int *)0, &hip)) {
+ 		for (j = n; j-- > 0; )
+ 			for (i = nh; i-- > 0; ) {
+ 				if (dtids[j] == hip[i].hi_tid) {
+ 					hc_add(&hip[i]);
+ 					if (addcallback)
+ 						addcallback(dtids[j]);
+ 					d++;
+ 					break;
+ 				}
+ 			}
+ 	}
+ 	MY_FREE(dtids);
+ 	return d;
+ }
+ 
+ 
+ /*	host_delete()
+ *
+ *	Called when a HostDelete notify message has been received.
+ *	The message is in the current receive buffer.
+ */
+ 
+ host_delete()
+ {
+ 	int tid;
+ 	struct hostc *hp;
+ 	int d = 0;
+ 
+ 	pvm_upkint(&tid, 1, 1);
+ 	if (tid == pvm_tidtohost(tid) && (hp = hc_find(tid))) {
+ 		if (delcallback)
+ 			delcallback(tid);
+ 		hc_delete(hp);
+ 		d++;
+ 	}
+ 	return d;
+ }
+ 
+ 
+ struct hostc *
+ host_findtid(tid)
+ 	int tid;
+ {
+ 	return hc_find(tid);
+ }
+ 
+ 
+ struct hostc *
+ host_findname(name)
+ 	char *name;
+ {
+ 	struct hostc *hp;
+ 
+ 	for (hp = curhosts->link; hp != curhosts; hp = hp->link)
+ 		if (!strcmp(name, hp->name))
+ 			return hp;
+ 	return (struct hostc *)0;
+ }
+ 
+ 
+ struct hostc *
+ host_next(hp)
+ 	struct hostc *hp;
+ {
+ 	hp = hp ? hp->link : curhosts->link;
+ 	return (hp == curhosts) ? 0 : hp;
+ }
+ 
+ 
+ host_show()
+ {
+ 	struct hostc *hp;
+ 	int nh = 0;
+ 	int na = 0;
+ 	int a;
+ 	long mask = 0;
+ 
+ 	for (hp = 0; hp = host_next(hp); ) {
+ 		nh++;
+ 		a = pvm_archcode(hp->arch);
+ 		if (!(mask & (1 << a))) {
+ 			na++;
+ 			mask |= (1 << a);
+ 		}
+ 	}
+ 	printf("Configuration: %d host%s, %d data format%s\n",
+ 			nh, (nh == 1 ? "" : "s"),
+ 			na, (na == 1 ? "" : "s"));
+ 	printf("     TID       ARCH   SPEED HOSTNAME\n");
+ 	for (hp = 0; hp = host_next(hp); ) {
+ 		printf("%8x %10s %7d %-24s\n",
+ 				hp->pvmd_tid,
+ 				hp->arch,
+ 				hp->speed,
+ 				hp->name);
+ 	}
+ }
+ 
+ 
*** /dev/null	Fri Nov 10 16:55:31 1995
--- misc/xhoster/hostc.h	Tue Oct 31 01:14:54 1995
***************
*** 0 ****
--- 1,62 ----
+ 
+ /*
+  *         PVM version 3.3:  Parallel Virtual Machine System
+  *               University of Tennessee, Knoxville TN.
+  *           Oak Ridge National Laboratory, Oak Ridge TN.
+  *                   Emory University, Atlanta GA.
+  *      Authors:  A. L. Beguelin, J. J. Dongarra, G. A. Geist,
+  *    W. C. Jiang, R. J. Manchek, B. K. Moore, and V. S. Sunderam
+  *                   (C) 1992 All Rights Reserved
+  *
+  *                              NOTICE
+  *
+  * Permission to use, copy, modify, and distribute this software and
+  * its documentation for any purpose and without fee is hereby granted
+  * provided that the above copyright notice appear in all copies and
+  * that both the copyright notice and this permission notice appear in
+  * supporting documentation.
+  *
+  * Neither the Institutions (Emory University, Oak Ridge National
+  * Laboratory, and University of Tennessee) nor the Authors make any
+  * representations about the suitability of this software for any
+  * purpose.  This software is provided ``as is'' without express or
+  * implied warranty.
+  *
+  * PVM version 3 was funded in part by the U.S. Department of Energy,
+  * the National Science Foundation and the State of Tennessee.
+  */
+ 
+ /*
+  *	hostc.h
+  *
+  *	Host cache definitions.
+  *
+ $Log$
+  */
+ 
+ 
+ struct hostc {
+ 	struct hostc *link, *rlink;
+ 	int pvmd_tid;
+ 	char *name;
+ 	char *alias;
+ 	char *arch;
+ 	int speed;
+ 	struct timeval delta;
+ };
+ 
+ 
+ int host_init __ProtoGlarp__(( int atag, int dtag, int (*acb)(), int (*dcb)() ));
+ 
+ int host_add __ProtoGlarp__(( void ));
+ 
+ int host_delete __ProtoGlarp__(( void ));
+ 
+ struct hostc *host_findtid __ProtoGlarp__(( int tid ));
+ 
+ struct hostc *host_findname __ProtoGlarp__(( char *name ));
+ 
+ struct hostc *host_next __ProtoGlarp__(( struct hostc *hp ));
+ 
+ int host_show __ProtoGlarp__(( void ));
+ 
*** /dev/null	Fri Nov 10 16:55:31 1995
--- misc/xhoster/myalloc.h	Tue Oct 31 01:14:55 1995
***************
*** 0 ****
--- 1,56 ----
+ 
+ /*
+  *         PVM version 3.3:  Parallel Virtual Machine System
+  *               University of Tennessee, Knoxville TN.
+  *           Oak Ridge National Laboratory, Oak Ridge TN.
+  *                   Emory University, Atlanta GA.
+  *      Authors:  A. L. Beguelin, J. J. Dongarra, G. A. Geist,
+  *    W. C. Jiang, R. J. Manchek, B. K. Moore, and V. S. Sunderam
+  *                   (C) 1992 All Rights Reserved
+  *
+  *                              NOTICE
+  *
+  * Permission to use, copy, modify, and distribute this software and
+  * its documentation for any purpose and without fee is hereby granted
+  * provided that the above copyright notice appear in all copies and
+  * that both the copyright notice and this permission notice appear in
+  * supporting documentation.
+  *
+  * Neither the Institutions (Emory University, Oak Ridge National
+  * Laboratory, and University of Tennessee) nor the Authors make any
+  * representations about the suitability of this software for any
+  * purpose.  This software is provided ``as is'' without express or
+  * implied warranty.
+  *
+  * PVM version 3 was funded in part by the U.S. Department of Energy,
+  * the National Science Foundation and the State of Tennessee.
+  */
+ 
+ /*
+  *	myalloc.h
+  *
+  *	Malloc defines.
+  *
+ $Log$
+  */
+ 
+ #ifdef HASSTDLIB
+ #include <stdlib.h>
+ #endif
+ 
+ #ifdef	USE_PVM_ALLOC
+ #define	MY_ALLOC(n,g)		pvm_alloc((unsigned)(n),(g))
+ #define	MY_REALLOC(p,n)	pvm_realloc((char*)(p),(unsigned)(n))
+ #define	MY_FREE(p)			pvm_free((char*)(p))
+ 
+ #else
+ #define	MY_ALLOC(n,g)		malloc((unsigned)(n))
+ #define	MY_REALLOC(p,n)		realloc((char*)(p),(unsigned)(n))
+ #define	MY_FREE(p)			free((char*)(p))
+ #endif
+ 
+ #define	TALLOC(n,t,g)		(t*)MY_ALLOC((n)*sizeof(t),(g))
+ #define	TREALLOC(p,n,t)		(t*)MY_REALLOC(p,(n)*sizeof(t))
+ 
+ #define	STRALLOC(s)			strcpy(TALLOC(strlen(s)+1,char,"str"),s)
+ 
*** /dev/null	Fri Nov 10 16:55:31 1995
--- misc/xhoster/xhoster.c	Tue Oct 31 01:14:58 1995
***************
*** 0 ****
--- 1,1125 ----
+ 
+ /*
+ *	xhoster.c
+ *
+ *	Example X-Window hoster.  Lets user type passwords without having
+ *	master pvmd running in foreground.
+ *	From hoster.c example.
+ *
+ *	21 Sep 1994  Manchek
+ */
+ 
+ #include <stdio.h>
+ #include <X11/Xlib.h>
+ #include <X11/Intrinsic.h>
+ #include <X11/StringDefs.h>
+ #include <X11/Shell.h>
+ #include <X11/Xaw/Label.h>
+ #include <X11/Xaw/Command.h>
+ #include <X11/Xaw/Form.h>
+ #include <X11/Xaw/AsciiText.h>
+ #include <sys/types.h>
+ #include <errno.h>
+ #include <pwd.h>
+ #include <netdb.h>
+ #if defined(IMA_RS6K) || defined(IMA_SP2MPI)
+ #include <sys/select.h>
+ #endif
+ #ifdef	SYSVSTR
+ #include <string.h>
+ #define	CINDEX(s,c)	strchr(s,c)
+ #else
+ #include <strings.h>
+ #define	CINDEX(s,c)	index(s,c)
+ #endif
+ #include <pvm3.h>
+ #include <pvmsdpro.h>
+ #include "hostc.h"
+ 
+ #ifndef	RSHCOMMAND
+ #define	RSHCOMMAND	"/usr/ucb/rsh"
+ #endif
+ 
+ #ifndef	RSHTIMEOUT
+ #define	RSHTIMEOUT	60
+ #endif
+ 
+ #ifndef	RSHNPLL
+ #define	RSHNPLL	5
+ #endif
+ 
+ #ifndef	max
+ #define	max(a,b)	((a)>(b)?(a):(b))
+ #endif
+ 
+ #ifndef	min
+ #define	min(a,b)	((a)<(b)?(a):(b))
+ #endif
+ 
+ #define	TALLOC(n,t,g)	(t*)malloc((n)*sizeof(t))
+ #define	FREE(p)	free((char *)p)
+ #define	STRALLOC(s)			strcpy(TALLOC(strlen(s)+1,char,"str"),s)
+ 
+ #define	LISTPUTAFTER(o,n,f,r) \
+ 	{ (n)->f=(o)->f; (n)->r=o; (o)->f->r=n; (o)->f=n; }
+ #define	LISTPUTBEFORE(o,n,f,r) \
+ 	{ (n)->r=(o)->r; (n)->f=o; (o)->r->f=n; (o)->r=n; }
+ #define	LISTDELETE(e,f,r) \
+ 	{ (e)->f->r=(e)->r; (e)->r->f=(e)->f; (e)->r=(e)->f=0; }
+ 
+ #define	TVCLEAR(tvp)	((tvp)->tv_sec = (tvp)->tv_usec = 0)
+ 
+ #define	TVISSET(tvp)	((tvp)->tv_sec || (tvp)->tv_usec)
+ 
+ #define	TVXLTY(xtv, ytv) \
+ 	((xtv)->tv_sec < (ytv)->tv_sec || \
+ 		((xtv)->tv_sec == (ytv)->tv_sec && (xtv)->tv_usec < (ytv)->tv_usec))
+ 
+ #define	TVXADDY(ztv, xtv, ytv)	\
+ 	if (((ztv)->tv_usec = (xtv)->tv_usec + (ytv)->tv_usec) < 1000000) {	\
+ 		(ztv)->tv_sec = (xtv)->tv_sec + (ytv)->tv_sec;	\
+ 	} else {	\
+ 		(ztv)->tv_usec -= 1000000;	\
+ 		(ztv)->tv_sec = (xtv)->tv_sec + (ytv)->tv_sec + 1;	\
+ 	}
+ 
+ #define	TVXSUBY(ztv, xtv, ytv)	\
+ 	if ((xtv)->tv_usec >= (ytv)->tv_usec) {	\
+ 		(ztv)->tv_sec = (xtv)->tv_sec - (ytv)->tv_sec;	\
+ 		(ztv)->tv_usec = (xtv)->tv_usec - (ytv)->tv_usec;	\
+ 	} else {	\
+ 		(ztv)->tv_sec = (xtv)->tv_sec - (ytv)->tv_sec - 1;	\
+ 		(ztv)->tv_usec = (xtv)->tv_usec + 1000000 - (ytv)->tv_usec;	\
+ 	}
+ 
+ #define	BZERO(p,n)	bzero((p),(n))
+ 
+ /*
+ *	for keeping state assoc. with a host
+ */
+ 
+ struct hst {
+ 	int h_tid;
+ 	char *h_name;
+ 	char *h_login;
+ 	char *h_sopts;
+ 	int h_flag;
+ #define	HST_PASSWORD	1		/* ask for a password */
+ #define	HST_MANUAL		2		/* do manual startup */
+ 	char *h_pwd;
+ 	char *h_cmd;
+ 	char *h_result;
+ };
+ 
+ #define	STA_IDLE	0
+ #define	STA_NEEDPW	1
+ #define	STA_START	2
+ 
+ #define	HostAdded	1		/* for notify */
+ #define	HostDeleted	2
+ 
+ 
+ int debugmask = 0;
+ char *username = 0;
+ Display *xDisp = 0;
+ XtAppContext context = 0;
+ Widget topLevel = 0;		/* main widget */
+ int xScrn = 0;
+ Window xRootW = 0;
+ char pwbuffer[30];
+ Widget pwdWindow = 0;
+ Widget logWindow = 0;
+ Widget okButton = 0;
+ Widget okallButton = 0;
+ Widget hostsLabel = 0;
+ int mystate = STA_IDLE;			/* state of widgy */
+ struct hst **hostlist = 0;		/* hosts being added */
+ int numhost = 0;				/* number of hosts */
+ int fromtid = 0;				/* source tid of add request */
+ int fromwid = 0;				/* wait id in request */
+ int curhost = 0;				/* waiting for password for this host */
+ char scribble[1024];
+ 
+ static Arg args[16];
+ static XtCallbackRec callback[2] = { { 0, 0 }, { 0, 0 } };
+ 
+ static char *fallbacks[] = {
+ 	"*titleLabel.label: PVM Xhoster",
+ 	"*titleLabel.borderWidth: 0",
+ 	"*hostsLabel.borderWidth: 0",
+ 	"*pwdLabel.label: Password:",
+ 	"*pwdLabel.borderWidth: 0",
+ 	"*quitButton.label: Exit",
+ 	"*hbox.borderWidth: 0",
+ 	"*okButton.label: Ok",
+ 	"*okallButton.label: Ok-for-all",
+ 	"*logWindow.width: 400",
+ 	"*logWindow.height: 90",
+ 	"*logWindow.scrollHorizontal: Always",
+ 	"*logWindow.scrollVertical: Always",
+ 	0
+ };
+ 
+ typedef struct {
+ 	Bool mono;			/* force monochrome display */
+ } app_res_t, *app_resp_t;
+ 
+ static app_res_t app_res;
+ 
+ static XtResource res_list[] = {
+ 	{ "monochrome", "Monochrome", XtRBool, sizeof(Bool),
+ 		XtOffset(app_resp_t, mono), XtRString, "off" },
+ };
+ 
+ static XrmOptionDescRec knownargs[] = {
+ 	{ "-mono", ".monochrome", XrmoptionNoArg, "on" },
+ 	{ "+mono", ".monochrome", XrmoptionNoArg, "off" },
+ };
+ 
+ 
+ void pvm_cb();
+ void quit_cb();
+ 
+ 
+ hostcount()
+ {
+ 	int nh = 0;
+ 	struct hostc *hp = 0;
+ 
+ 	while (hp = host_next(hp))
+ 		nh++;
+ 	sprintf(scribble, "Hosts:%3d", nh);
+ 	XtSetArg(args[0], XtNlabel, scribble);
+ 	XtSetValues(hostsLabel, args, 1);
+ }
+ 
+ 
+ host_was_added(tid)
+ 	int tid;
+ {
+ 	return 0;
+ }
+ 
+ 
+ host_was_deleted(tid)
+ 	int tid;
+ {
+ 	struct hostc *hp;
+ 
+ 	if (hp = host_findtid(tid)) {
+ 		sprintf(scribble, "Host %s deleted\n", hp->name);
+ 		log_this(scribble);
+ 	}
+ 	return 0;
+ }
+ 
+ 
+ main(argc, argv)
+ 	int argc;
+ 	char **argv;
+ {
+ 	struct passwd *pe;
+ 	int uid;
+ 	int n;
+ 	int *fds;
+ 	int didstart = 0;
+ 
+ 	n = 0;
+ 	topLevel = XtAppInitialize(&context, "xhoster",
+ 		knownargs, XtNumber(knownargs),
+ 		&argc, argv,
+ 		fallbacks,
+ 		args, n);
+ 
+ /*
+ 	XtGetApplicationResources(topLevel, (caddr_t)&app_res,
+ 		res_list, XtNumber(res_list), 0, 0);
+ */
+ 
+ 	pvm_setopt(PvmRoute, PvmDontRoute);
+ 
+ 	if (pvm_mytid() < 0) {
+ 		if (pvm_start_pvmd(0, (char **)0, 1) < 0)
+ 			exit(1);
+ 		didstart = 1;
+ 	}
+ 
+ /*
+ 	XtAppAddActions(context, actbl, XtNumber(actbl));
+ */
+ 
+ 	xDisp = XtDisplay(topLevel);
+ 	xScrn = DefaultScreen(xDisp);
+ 	xRootW = RootWindow(xDisp, xScrn);
+ 
+ 	create_widget();
+ 
+ 	if ((uid = getuid()) == -1) {
+ 		fprintf(stderr, "main() can't getuid()\n");
+ 		exit(1);
+ 	}
+ 	if (pe = getpwuid(uid))
+ 		username = STRALLOC(pe->pw_name);
+ 	else
+ 		fprintf(stderr, "main() can't getpwuid\n");
+ 	endpwent();
+ 
+ 	pvm_setopt(PvmResvTids, 1);
+ 	pvm_reg_hoster();
+ 
+ 	host_init(HostAdded, HostDeleted, host_was_added, host_was_deleted);
+ 
+ 	pvm_getfds(&fds);
+ 	XtAppAddInput(context, fds[0], (XtPointer)XtInputReadMask,
+ 			pvm_cb, (XtPointer)0);
+ 
+ 	if (didstart)
+ 		log_this("No pvmd found, started one");
+ 	log_this("PVM Xhoster ready");
+ 	XtAppMainLoop(context);
+ 
+ 	pvm_exit();	/* not reached */
+ 	exit(0);
+ }
+ 
+ 
+ void
+ pvm_cb(cli, src, id)
+ 	XtPointer cli;
+ 	int *src;
+ 	XtInputId *id;
+ {
+ 	int tag;
+ 
+ 	while (pvm_nrecv(-1, -1) > 0) {
+ 		pvm_bufinfo(pvm_getrbuf(), (int *)0, (int *)&tag, (int *)0);
+ 		if (tag == SM_STHOST)
+ 			hoster();
+ 		if (tag == HostAdded) {
+ 			host_add();
+ 			hostcount();
+ 		}
+ 		if (tag == HostDeleted) {
+ 			host_delete();
+ 			hostcount();
+ 		}
+ 	}
+ }
+ 
+ 
+ void
+ ok_cb(wgt, cli, cd)
+ 	Widget wgt;
+ 	caddr_t cli;
+ 	caddr_t cd;
+ {
+ 	int n;
+ 
+ 	if (mystate == STA_NEEDPW)
+ 		hostlist[curhost]->h_pwd = STRALLOC(pwbuffer);
+ /*
+ 	else
+ 		TextAppend(logWindow, "what?\n", 6);
+ */
+ 	BZERO(pwbuffer, sizeof(pwbuffer));
+ 	n = 0;
+ 	XtSetArg(args[n], XtNstring, pwbuffer); n++;
+ 	XtSetValues(pwdWindow, args, n);
+ 	if (mystate == STA_NEEDPW)
+ 		next_pwd();
+ }
+ 
+ 
+ void
+ okall_cb(wgt, cli, cd)
+ 	Widget wgt;
+ 	caddr_t cli;
+ 	caddr_t cd;
+ {
+ 	int n;
+ 
+ 	if (mystate == STA_NEEDPW) {
+ 		while (curhost < numhost) {
+ 			if (hostlist[curhost]->h_flag & HST_PASSWORD)
+ 				hostlist[curhost]->h_pwd = STRALLOC(pwbuffer);
+ 			curhost++;
+ 		}
+ 		log_this("Using password for all hosts\n");
+ 	}
+ 	BZERO(pwbuffer, sizeof(pwbuffer));
+ 	n = 0;
+ 	XtSetArg(args[n], XtNstring, pwbuffer); n++;
+ 	XtSetValues(pwdWindow, args, n);
+ 	if (mystate == STA_NEEDPW)
+ 		hoster2();
+ }
+ 
+ 
+ void
+ quit_cb(wgt, cli, cd)
+ 	Widget wgt;
+ 	caddr_t cli;
+ 	caddr_t cd;
+ {
+ 	pvm_exit();
+ 	exit(0);
+ }
+ 
+ 
+ log_this(s)
+ 	char *s;
+ {
+ /*
+ 	int n;
+ 
+ 	n = 0;
+ 	XtSetArg(args[n], XtNlabel, s); n++;
+ 	XtSetValues(stateLabel, args, n);
+ */
+ 	TextAppend(logWindow, s, strlen(s));
+ 	if (s[strlen(s) - 1] != '\n')
+ 		TextAppend(logWindow, "\n", 1);
+ }
+ 
+ 
+ long
+ TextLength(w)
+ 	Widget w;
+ {
+ 	return XawTextSourceScan(XawTextGetSource(w),
+ 			(XawTextPosition)0, XawstAll, XawsdRight, 1, TRUE);
+ }
+ 
+ 
+ TextReplace(w, start, end, block)
+ 	Widget w;
+ 	XawTextBlock *block;
+ {
+ 	Arg arg;
+ 	Widget source;
+ 	XawTextEditType edit_mode;
+ 
+ 	source = XawTextGetSource(w);
+ 	XtSetArg(arg, XtNeditType, &edit_mode);
+ 	XtGetValues(source, &arg, 1);
+ 	XtSetArg(arg, XtNeditType, XawtextEdit);
+ 	XtSetValues(source, &arg, 1);
+ 	XawTextReplace(w, start, end, block);
+ 	XtSetArg(arg, XtNeditType, edit_mode);
+ 	XtSetValues(source, &arg, 1);
+ }
+ 
+ 
+ TextAppend(w, s, len)
+ 	Widget w;
+ 	char *s;
+ {
+ 	long last, current;
+ 	XawTextBlock block;
+ 
+ 	current = XawTextGetInsertionPoint(w);
+ 	last = TextLength(w);
+ 	block.ptr = s;
+ 	block.firstPos = 0;
+ 	block.length = len;
+ 	block.format = FMT8BIT;
+ 	TextReplace(w, last, last, &block);
+ 	if (current == last)
+ 		XawTextSetInsertionPoint(w, last + block.length);
+ }
+ 
+ 
+ create_widget()
+ {
+ 	Widget box, hbox;
+ 	Widget w, w2;
+ 	int n;
+ /*
+ 	Pixmap pm;
+ */
+ 	XtAccelerators atbl;
+ 	int nh;
+ 
+ 	atbl = XtParseAcceleratorTable("#override\n<Key>Return:set()notify()reset()\n");
+ 
+ 	n = 0;
+ 	box = XtCreateManagedWidget("", formWidgetClass, topLevel, args, n);
+ 
+ 	n = 0;
+ 	XtSetArg(args[n], XtNtop, XawChainTop); n++;
+ 	XtSetArg(args[n], XtNbottom, XawChainTop); n++;
+ 	XtSetArg(args[n], XtNleft, XawChainLeft); n++;
+ 	XtSetArg(args[n], XtNright, XawChainLeft); n++;
+ 	hbox = XtCreateManagedWidget("hbox", formWidgetClass, box, args, n);
+ 
+ 	n = 0;
+ 	sprintf(scribble, "PVM Xhoster (task id =t%x)", pvm_mytid());
+ 	XtSetArg(args[n], XtNlabel, scribble); n++;
+ 	w = XtCreateManagedWidget("titleLabel", labelWidgetClass,
+ 			hbox, args, n);
+ 
+ 	n = 0;
+ 	XtSetArg(args[n], XtNfromHoriz, w); n++;
+ 	pvm_config(&nh, (int *)0, (struct pvmhostinfo **)0);
+ 	sprintf(scribble, "Hosts:%3d", nh);
+ 	XtSetArg(args[n], XtNlabel, scribble); n++;
+ 	w = hostsLabel = XtCreateManagedWidget("hostsLabel", labelWidgetClass,
+ 			hbox, args, n);
+ 
+ 	n = 0;
+ 	XtSetArg(args[n], XtNfromHoriz, w); n++;
+ 	callback[0].callback = (XtCallbackProc)quit_cb;
+ 	callback[0].closure = (caddr_t)0;
+ 	XtSetArg(args[n], XtNcallback, callback); n++;
+ /*
+ 	pm = XCreatePixmapFromBitmapData(xDisp, xRootW,
+ 			quit_bits, quit_width, quit_height, 1, 0, 1);
+ 	XtSetArg(args[n], XtNbitmap, (XtArgVal)pm); n++;
+ */
+ 	w = XtCreateManagedWidget("quitButton", commandWidgetClass,
+ 			hbox, args, n);
+ 
+ 	n = 0;
+ 	XtSetArg(args[n], XtNfromVert, hbox); n++;
+ 	XtSetArg(args[n], XtNtop, XawChainTop); n++;
+ 	XtSetArg(args[n], XtNbottom, XawChainBottom); n++;
+ 	XtSetArg(args[n], XtNleft, XawChainLeft); n++;
+ 	XtSetArg(args[n], XtNright, XawChainRight); n++;
+ 	hbox = logWindow = XtCreateManagedWidget("logWindow", asciiTextWidgetClass,
+ 			box, args, n);
+ 
+ 	n = 0;
+ 	XtSetArg(args[n], XtNfromVert, hbox); n++;
+ 	XtSetArg(args[n], XtNtop, XawChainBottom); n++;
+ 	XtSetArg(args[n], XtNbottom, XawChainBottom); n++;
+ 	XtSetArg(args[n], XtNleft, XawChainLeft); n++;
+ 	XtSetArg(args[n], XtNright, XawChainLeft); n++;
+ 	hbox = XtCreateManagedWidget("hbox", formWidgetClass, box, args, n);
+ 
+ 	n = 0;
+ 	XtSetArg(args[n], XtNeditType, XawtextEdit); n++;
+ 	w = XtCreateManagedWidget("pwdLabel", labelWidgetClass,
+ 			hbox, args, n);
+ 
+ 	n = 0;
+ 	XtSetArg(args[n], XtNfromHoriz, w); n++;
+ 	XtSetArg(args[n], XtNeditType, XawtextEdit); n++;
+ 	XtSetArg(args[n], XtNstring, pwbuffer); n++;
+ 	XtSetArg(args[n], XtNlength, sizeof(pwbuffer)-1); n++;
+ 	XtSetArg(args[n], XtNuseStringInPlace, True); n++;
+ 	XtSetArg(args[n], XtNecho, False); n++;
+ 	w = pwdWindow = XtCreateManagedWidget("pwdWindow", asciiTextWidgetClass,
+ 			hbox, args, n);
+ 
+ 	n = 0;
+ 	XtSetArg(args[n], XtNfromHoriz, w); n++;
+ 	callback[0].callback = (XtCallbackProc)ok_cb;
+ 	callback[0].closure = (caddr_t)0;
+ 	XtSetArg(args[n], XtNcallback, callback); n++;
+ 	XtSetArg(args[n], XtNaccelerators, atbl); n++;
+ 	w = okButton = XtCreateManagedWidget("okButton", commandWidgetClass,
+ 			hbox, args, n);
+ 
+ 	n = 0;
+ 	XtSetArg(args[n], XtNfromHoriz, w); n++;
+ 	callback[0].callback = (XtCallbackProc)okall_cb;
+ 	callback[0].closure = (caddr_t)0;
+ 	XtSetArg(args[n], XtNcallback, callback); n++;
+ 	XtSetArg(args[n], XtNaccelerators, atbl); n++;
+ 	w = okallButton = XtCreateManagedWidget("okallButton", commandWidgetClass,
+ 			hbox, args, n);
+ 
+ 	XtRealizeWidget(topLevel);
+ 	XtInstallAccelerators(pwdWindow, okButton);
+ }
+ 
+ 
+ /*	hoster()
+ *
+ *	Unpack host table from message, attempt to start 'em up,
+ *	send reply message.
+ */
+ 
+ hoster()
+ {
+ 	int i;
+ 	struct hst *hp;
+ 	char *p;
+ 	char sopts[64];
+ 	char lognam[256];
+ 	char cmd[512];
+ 
+ 	/*
+ 	* unpack the startup message
+ 	*/
+ 
+ 	pvm_bufinfo(pvm_getrbuf(), (int *)0, (int *)0, &fromtid);
+ 	pvm_unpackf("%d", &numhost);
+ 	fromwid = pvm_getmwid(pvm_getrbuf());
+ 
+ 	if (numhost > 0) {
+ 		log_this("Ready to add hosts:\n");
+ 		hostlist = TALLOC(numhost, struct hst *, "xxx");
+ 		for (i = 0; i < numhost; i++) {
+ 			hp = TALLOC(1, struct hst, "xxx");
+ 			BZERO((char *)hp, sizeof(struct hst));
+ 			hostlist[i] = hp;
+ 			if (pvm_unpackf("%d %s %s %s", &hp->h_tid, sopts, lognam, cmd)) {
+ 				log_this("received message with bad format\n");
+ 				return 1;
+ 			}
+ 			hp->h_sopts = STRALLOC(sopts);
+ 			hp->h_login = STRALLOC(lognam);
+ 			hp->h_cmd = STRALLOC(cmd);
+ 			sprintf(scribble, "%2d. %s\n", i + 1, hp->h_login);
+ 			log_this(scribble);
+ 			if (debugmask)
+ 				fprintf(stderr, "%d. t%x %s so=\"%s\"\n", i,
+ 						hp->h_tid,
+ 						hp->h_login,
+ 						hp->h_sopts);
+ 
+ 			if (p = CINDEX(hp->h_login, '@')) {
+ 				hp->h_name = STRALLOC(p + 1);
+ 				*p = 0;
+ 				p = STRALLOC(hp->h_login);
+ 				FREE(hp->h_login);
+ 				hp->h_login = p;
+ 
+ 			} else {
+ 				hp->h_name = hp->h_login;
+ 				hp->h_login = 0;
+ 			}
+ 			if (!strcmp(hp->h_sopts, "pw"))
+ 				hp->h_flag |= HST_PASSWORD;
+ 			if (!strcmp(hp->h_sopts, "ms"))
+ 				hp->h_flag |= HST_MANUAL;
+ 		}
+ 	}
+ 	curhost = -1;
+ 	next_pwd();
+ 	return 0;
+ }
+ 
+ 
+ next_pwd()
+ {
+ 	char buf[256];
+ 
+ 	while (1) {
+ 		curhost++;
+ 		if (curhost >= numhost) {
+ 			hoster2();
+ 			break;
+ 	
+ 		} else
+ 			if (hostlist[curhost]->h_flag & HST_PASSWORD) {
+ 				mystate = STA_NEEDPW;
+ 				sprintf(buf, "Enter password for %s:\n",
+ 						hostlist[curhost]->h_name);
+ 				log_this(buf);
+ 				break;
+ 			}
+ 	}
+ }
+ 
+ 
+ hoster2()
+ {
+ 	int i;
+ 	char *p;
+ 	struct hst *hp;
+ 
+ 	/*
+ 	* do it
+ 	*/
+ 
+ 	mystate = STA_START;
+ 	log_this("Starting...");
+ 	XFlush(xDisp);
+ 
+ 	pl_startup(numhost, hostlist);
+ 
+ 	/*
+ 	* send results back to pvmd
+ 	*/
+ 
+ 	pvm_packf("%+ %d", PvmDataFoo, numhost);
+ 	for (i = 0; i < numhost; i++) {
+ 		pvm_packf("%d", hostlist[i]->h_tid);
+ 		pvm_packf("%s", hostlist[i]->h_result
+ 				? hostlist[i]->h_result : "PvmDSysErr");
+ 	}
+ 
+ 	pvm_setmwid(pvm_getsbuf(), fromwid);
+ 	pvm_send(fromtid, SM_STHOSTACK);
+ 
+ 	mystate = STA_IDLE;
+ 	log_this("...Done");
+ 
+ 	for (i = 0; i < numhost; i++) {
+ 		hp = hostlist[i];
+ 		if (hp->h_name)
+ 			FREE(hp->h_name);
+ 		if (hp->h_login)
+ 			FREE(hp->h_login);
+ 		if (hp->h_sopts)
+ 			FREE(hp->h_sopts);
+ 		if (hp->h_pwd) {
+ 			for (p = hp->h_pwd; *p; p++)
+ 				*p = 0;
+ 			FREE(hp->h_pwd);
+ 		}
+ 		if (hp->h_cmd)
+ 			FREE(hp->h_cmd);
+ 		if (hp->h_result)
+ 			FREE(hp->h_result);
+ 		FREE(hp);
+ 	}
+ 	FREE(hostlist);
+ 	hostlist = 0;
+ 	numhost = 0;
+ 
+ 	return 0;
+ }
+ 
+ 
+ /********************************************
+ *  this is the new (parallel) startup code  *
+ *                                           *
+ ********************************************/
+ 
+ struct slot {
+ 	struct slot *s_link, *s_rlink;		/* free/active list */
+ 	struct hst *s_hst;					/* host table entry */
+ 	struct timeval s_bail;				/* timeout time */
+ 	int s_rfd, s_wfd, s_efd;			/* slave stdin/out/err */
+ 	char s_buf[256];					/* config reply line */
+ 	int s_len;							/* length of s_buf */
+ };
+ 
+ 
+ static struct slot slots[RSHNPLL+2];	/* state var/context for each slot */
+ static struct slot *slfree = 0;			/* free list of slots */
+ 
+ close_slot(sp)
+ 	struct slot *sp;
+ {
+ 	if (sp->s_wfd != -1)
+ 		(void)close(sp->s_wfd);
+ 	if (sp->s_rfd != -1)
+ 		(void)close(sp->s_rfd);
+ 	if (sp->s_efd != -1)
+ 		(void)close(sp->s_efd);
+ 	LISTDELETE(sp, s_link, s_rlink);
+ 	LISTPUTBEFORE(slfree, sp, s_link, s_rlink);
+ 	return 0;
+ }
+ 
+ 
+ pl_startup(num, hostlist)
+ 	int num;
+ 	struct hst **hostlist;
+ {
+ 	int nxth = 0;						/* next host in list to start */
+ 	struct slot *slact = 0;				/* active list of slots */
+ 	struct hst *hp;
+ 	struct slot *sp, *sp2;
+ 	struct timeval tnow;
+ 	struct timeval tout;
+ 	struct fd_set rfds;
+ 	int nfds;
+ 	int i;
+ 	int n;
+ 	char *p, *q;
+ 	char ebuf[256];						/* for reading stderr */
+ 
+ 	/* init slot free list */
+ 
+ 	slfree = &slots[RSHNPLL+1];
+ 	slfree->s_link = slfree->s_rlink = slfree;
+ 	slact = &slots[RSHNPLL];
+ 	slact->s_link = slact->s_rlink = slact;
+ 	for (i = RSHNPLL; i-- > 0; ) {
+ 		LISTPUTAFTER(slfree, &slots[i], s_link, s_rlink);
+ 	}
+ 
+ 	/*
+ 	* keep at this until all hosts in table are completed
+ 	*/
+ 
+ 	for (; ; ) {
+ 
+ 		/*
+ 		* if empty slots, start on new hosts
+ 		*/
+ 
+ 		for (; ; ) {
+ 
+ 			/* find a host for slot */
+ 
+ 			if (slfree->s_link != slfree && nxth < num)
+ 				hp = hostlist[nxth++];
+ 			else
+ 				break;
+ 
+ 			sp = slfree->s_link;
+ 			LISTDELETE(sp, s_link, s_rlink);
+ 			sp->s_hst = hp;
+ 			sp->s_len = 0;
+ 			if (debugmask) {
+ 				fprintf(stderr, "pl_startup() trying %s\n", hp->h_name);
+ 			}
+ 			phase1(sp);
+ 			if (hp->h_result) {
+ 				/* error or fully started (manual startup) */
+ 
+ 				LISTPUTBEFORE(slfree, sp, s_link, s_rlink);
+ 
+ 			} else {
+ 				/* partially started */
+ 
+ 				LISTPUTBEFORE(slact, sp, s_link, s_rlink);
+ 				gettimeofday(&sp->s_bail, (struct timezone*)0);
+ 				tout.tv_sec = RSHTIMEOUT;
+ 				tout.tv_usec = 0;
+ 				TVXADDY(&sp->s_bail, &sp->s_bail, &tout);
+ 			}
+ 		}
+ 
+ 		/* if no hosts in progress, we are finished */
+ 
+ 		if (slact->s_link == slact)
+ 			break;
+ 
+ 		/*
+ 		* until next timeout, get output from any slot
+ 		*/
+ 
+ 		FD_ZERO(&rfds);
+ 		nfds = 0;
+ 		TVCLEAR(&tout);
+ 		gettimeofday(&tnow, (struct timezone*)0);
+ 		for (sp = slact->s_link; sp != slact; sp = sp->s_link) {
+ 			if (TVXLTY(&sp->s_bail, &tnow)) {
+ 				sprintf(scribble, "Giving up on %s after %d secs\n",
+ 						sp->s_hst->h_name, RSHTIMEOUT);
+ 				log_this(scribble);
+ 				sp->s_hst->h_result = STRALLOC("PvmCantStart");
+ 				sp2 = sp->s_rlink;
+ 				close_slot(sp);
+ 				sp = sp2;
+ 				continue;
+ 			}
+ 
+ 			if (!TVISSET(&tout) || TVXLTY(&sp->s_bail, &tout))
+ 				tout = sp->s_bail;
+ 			if (sp->s_rfd >= 0)
+ 				FD_SET(sp->s_rfd, &rfds);
+ 			if (sp->s_rfd > nfds)
+ 				nfds = sp->s_rfd;
+ 			if (sp->s_efd >= 0)
+ 				FD_SET(sp->s_efd, &rfds);
+ 			if (sp->s_efd > nfds)
+ 				nfds = sp->s_efd;
+ 		}
+ 
+ 		if (slact->s_link == slact)
+ 			break;
+ 
+ 		nfds++;
+ 
+ 		if (TVXLTY(&tnow, &tout)) {
+ 			TVXSUBY(&tout, &tout, &tnow);
+ 		} else {
+ 			TVCLEAR(&tout);
+ 		}
+ 		if (debugmask) {
+ 			fprintf(stderr, "pl_startup() select timeout is %d.%06d\n",
+ 					tout.tv_sec, tout.tv_usec);
+ 		}
+ 		if ((n = select(nfds, &rfds, (fd_set*)0, (fd_set*)0, &tout)) == -1) {
+ 			if (errno != EINTR) {
+ 				pvmlogperror("work() select");
+ 				pvmbailout(0);
+ 			}
+ 		}
+ 		if (debugmask) {
+ 			(void)fprintf(stderr, "pl_startup() select returns %d\n", n);
+ 		}
+ 		if (n < 1) {
+ 			if (n == -1 && errno != EINTR) {
+ 				pvmlogperror("pl_startup() select");
+ 				pvmbailout(0);	/* XXX this is too harsh */
+ 			}
+ 			continue;
+ 		}
+ 
+ 		/*
+ 		* check for response on stdout or stderr of any slave.
+ 		*/
+ 
+ 		for (sp = slact->s_link; sp != slact; sp = sp->s_link) {
+ 
+ 			/*
+ 			* stdout ready.  get complete line then scan config info from it.
+ 			*/
+ 			if (sp->s_rfd >= 0 && FD_ISSET(sp->s_rfd, &rfds)) {
+ 				n = read(sp->s_rfd, sp->s_buf + sp->s_len,
+ 						sizeof(sp->s_buf) - sp->s_len);
+ 				if (n > 0) {
+ 					sp->s_len += n;
+ 					if (sp->s_len >= sizeof(sp->s_buf)) {
+ 						sprintf(scribble, "Got gibberish back from %s\n",
+ 								sp->s_hst->h_name);
+ 						log_this(scribble);
+ 						sp->s_hst->h_result = STRALLOC("PvmCantStart");
+ 					}
+ 					sp->s_buf[sp->s_len] = 0;
+ 					if (p = CINDEX(sp->s_buf + sp->s_len - n, '\n')) {
+ 						if (debugmask) {
+ 							sprintf(scribble, "From %s: %s",
+ 									sp->s_hst->h_name, sp->s_buf);
+ 							log_this(scribble);
+ 						}
+ 						*p = 0;
+ 						sp->s_hst->h_result = STRALLOC(sp->s_buf);
+ 						if (!strncmp(sp->s_hst->h_result, "ddpro", 5)) {
+ 							sprintf(scribble, "Host %s ok\n",
+ 									sp->s_hst->h_name);
+ 							log_this(scribble);
+ 						}
+ 					}
+ 
+ 				} else {
+ 					if (n) {
+ 						fprintf(stderr, "pl_startup() pvmd@%s\n",
+ 								sp->s_hst->h_name);
+ 						perror("");
+ 					} else {
+ 						sprintf(scribble, "From %s: EOF\n",
+ 								sp->s_hst->h_name);
+ 						log_this(scribble);
+ 					}
+ 					sp->s_hst->h_result = STRALLOC("PvmCantStart");
+ 				}
+ 				if (sp->s_hst->h_result) {
+ 					sp2 = sp->s_rlink;
+ 					close_slot(sp);
+ 					sp = sp2;
+ 					continue;
+ 				}
+ 			}
+ 
+ 			/*
+ 			* response on stderr.  log prefixed by remote's host name.
+ 			*/
+ 			if (sp->s_efd >= 0 && FD_ISSET(sp->s_efd, &rfds)) {
+ 				if ((n = read(sp->s_efd, ebuf, sizeof(ebuf)-1)) > 0) {
+ 					char *p = ebuf, *q, c;
+ 
+ 					ebuf[n] = 0;
+ 					sprintf(scribble, "From %s stderr: ",
+ 							sp->s_hst->h_name);
+ 					q = scribble + strlen(scribble);
+ 					while (c = *p++ & 0x7f) {
+ 						if (isprint(c))
+ 							*q++ = c;
+ /*
+ 							fputc(c, stderr);
+ */
+ 
+ 						else {
+ 							*q++ = '^';
+ 							*q++ = (c + '@') & 0x7f;
+ /*
+ 							fputc('^', stderr);
+ 							fputc((c + '@') & 0x7f, stderr);
+ */
+ 						}
+ 					}
+ 					*q++ = '\n';
+ 					*q++ = 0;
+ 					log_this(scribble);
+ /*
+ 					fputc('\n', stderr);
+ */
+ 
+ 				} else {
+ 					(void)close(sp->s_efd);
+ 					sp->s_efd = -1;
+ 				}
+ 			}
+ 		}
+ 	}
+ 	return 0;
+ }
+ 
+ 
+ phase1(sp)
+ 	struct slot *sp;
+ {
+ 	struct hst *hp;
+ 	char *hn;
+ 	char *av[16];			/* for rsh args */
+ 	int ac;
+ 	char buf[512];
+ 	int pid = -1;			/* pid of rsh */
+ 	char *p;
+ 
+ #ifndef NOREXEC
+ 	struct servent *se;
+ 	static u_short execport = 0;
+ 
+ 	if (!execport) {
+ 		if (!(se = getservbyname("exec", "tcp"))) {
+ 			fprintf(stderr, "phase1() can't getservbyname(): %s\n", "exec");
+ 			pvmbailout(0);
+ 		}
+ 		execport = se->s_port;
+ 		endservent();
+ 	}
+ #endif
+ 
+ 	hp = sp->s_hst;
+ 	hn = hp->h_name;
+ 	sp->s_rfd = sp->s_wfd = sp->s_efd = -1;
+ 
+ 	/*
+ 	* XXX manual startup hack... this is if we can't use rexec or rsh
+ 	*/
+ 
+ 	if (hp->h_flag & HST_MANUAL) {
+ 		sprintf(scribble, "Can't start %s, manual startup specified\n",
+ 				hp->h_name);
+ 		log_this(scribble);
+ 		hp->h_result = STRALLOC("PvmNotImpl");
+ #if 0
+ 		fprintf(stderr, "*** Manual startup ***\n");
+ 		fprintf(stderr, "Login to \"%s\" and type:\n", hn);
+ 		fprintf(stderr, "%s\n", hp->h_cmd);
+ 
+ 	/* get version */
+ 
+ 		fprintf(stderr, "Type response: ");
+ 		fflush(stderr);
+ 		if (!(fgets(buf, sizeof(buf), stdin))) {
+ 			fprintf(stderr, "host %s read error\n", hn);
+ 			goto oops;
+ 		}
+ 		p = buf + strlen(buf) - 1;
+ 		if (*p == '\n')
+ 			*p = 0;
+ 		hp->h_result = STRALLOC(buf);
+ 		fprintf(stderr, "Thanks\n");
+ 		fflush(stderr);
+ #endif
+ 		return 0;
+ 	}
+ 
+ 	/*
+ 	* XXX end manual startup hack
+ 	*/
+ 
+ 	if (!(hp->h_flag & HST_PASSWORD)) {		/* use rsh to start */
+ 		int wpfd[2], rpfd[2], epfd[2];
+ 		int i;
+ 
+ 		if (debugmask) {
+ 			fprintf(stderr, "phase1() trying rsh to %s\n", hn);
+ 		}
+ 
+ 	/* fork an rsh to startup the slave pvmd */
+ 
+ #ifdef	IMA_TITN
+ 		if (socketpair(AF_UNIX, SOCK_STREAM, 0, wpfd) == -1
+ 		|| socketpair(AF_UNIX, SOCK_STREAM, 0, rpfd) == -1
+ 		|| socketpair(AF_UNIX, SOCK_STREAM, 0, epfd) == -1) {
+ 			pvmlogperror("phase1() socketpair");
+ 			goto oops;
+ 		}
+ #else
+ 		if (pipe(wpfd) == -1 || pipe(rpfd) == -1 || pipe(epfd) == -1) {
+ 			pvmlogperror("phase1() pipe");
+ 			goto oops;
+ 		}
+ #endif
+ 
+ 		if (debugmask) {
+ 			fprintf(stderr, "phase1() pipes: %d %d %d %d %d %d\n",
+ 					wpfd[0], wpfd[1], rpfd[0], rpfd[1], epfd[0], epfd[1]);
+ 		}
+ 
+ 		if ((pid = fork()) == -1) {
+ 			pvmlogperror("phase1() fork");
+ 			pvmbailout(0);
+ 		}
+ 		if (!pid) {
+ 			(void)dup2(wpfd[0], 0);
+ 			(void)dup2(rpfd[1], 1);
+ 			(void)dup2(epfd[1], 2);
+ 			for (i = getdtablesize(); --i > 2; )
+ 				(void)close(i);
+ 			ac = 0;
+ 			av[ac++] = RSHCOMMAND;
+ 			av[ac++] = hn;
+ 			if (hp->h_login) {
+ 				av[ac++] = "-l";
+ 				av[ac++] = hp->h_login;
+ 			}
+ 			av[ac++] = hp->h_cmd;
+ 			av[ac++] = 0;
+ 			if (debugmask) {
+ 				for (ac = 0; av[ac]; ac++)
+ 					fprintf(stderr, "av[%d]=\"%s\" ", ac, av[ac]);
+ 				fputc('\n', stderr);
+ 			}
+ 			execvp(av[0], av);
+ 			fputs("phase1() execvp failed\n", stderr);
+ 			fflush(stderr);
+ 			_exit(1);
+ 		}
+ 		(void)close(wpfd[0]);
+ 		(void)close(rpfd[1]);
+ 		(void)close(epfd[1]);
+ 		sp->s_wfd = wpfd[1];
+ 		sp->s_rfd = rpfd[0];
+ 		sp->s_efd = epfd[0];
+ 
+ 	} else {		/* use rexec to start */
+ 
+ #ifdef NOREXEC
+ 		log_this("Sorry, xhoster has been compiled without rexec()\n");
+ 		log_this("and can't take passwords\n");
+ 		goto oops;
+ #else
+ 		if (debugmask) {
+ 			fprintf(stderr, "phase1() rexec \"%s\"\n", hp->h_cmd);
+ 		}
+ 		if ((sp->s_wfd = sp->s_rfd = rexec(&hn, execport,
+ 				(hp->h_login ? hp->h_login : username),
+ 				(hp->h_flag & HST_PASSWORD ? hp->h_pwd : (char *)0),
+ 				hp->h_cmd, &sp->s_efd))
+ 		== -1) {
+ 			sprintf(scribble, "Permission denied for %s\n", hn);
+ 			log_this(scribble);
+ 			goto oops;
+ 		}
+ #endif
+ 	}
+ 	return 0;
+ 
+ oops:
+ 	hp->h_result = STRALLOC("PvmCantStart");
+ oops2:
+ 	if (sp->s_wfd != -1)
+ 		close(sp->s_wfd);
+ 	if (sp->s_rfd != -1)
+ 		close(sp->s_rfd);
+ 	if (sp->s_efd != -1)
+ 		close(sp->s_efd);
+ 	sp->s_wfd = sp->s_rfd = sp->s_efd = -1;
+ 	return 1;
+ }
+ 
+ 
*** ../netlib/pvm3.3.9/patches/Contents	Fri Sep  8 13:58:57 1995
--- patches/Contents	Fri Nov 10 16:49:37 1995
***************
*** 1,3 ****
--- 1,88 ----
+ patch #10
+ version:
+     3.3.9 -> 3.3.10
+ files:
+     patch  src/patchlevel.h
+     patch  Readme
+     patch  Readme.mp
+     create conf/ATT.def
+     create conf/ATT.m4
+     patch  conf/CUBE.def
+     patch  conf/E88K.def
+     patch  conf/FREEBSD.def
+     patch  conf/HPPAMP.def
+     patch  conf/RS6K.def
+     patch  conf/RS6KMP.def
+     patch  conf/SCO.def
+     patch  conf/SUN4SOL2.def
+     patch  conf/SUNMP.def
+     patch  conf/TITN.def
+     patch  conf/UTS2.def
+     create conf/X86SOL2.def
+     create conf/X86SOL2.m4
+     patch  console/cmds.c
+     patch  doc/bugreport
+     patch  lib/debugger
+     create lib/ipcfree
+     patch  lib/pvmgetarch
+     patch  man/man1/pvm_intro.1
+     patch  man/man1/pvmd3.1
+     create misc/README
+     create misc/group-hack-337
+     create misc/pvm_fork.c
+     create misc/xhoster/Imakefile
+     create misc/xhoster/README
+     create misc/xhoster/hostc.c
+     create misc/xhoster/hostc.h
+     create misc/xhoster/myalloc.h
+     create misc/xhoster/xhoster.c
+     patch  patches/Contents
+     patch  patches/README
+     create patches/README.339to10
+     patch  pvmgs/pvm_gstat.c
+     patch  pvmgs/pvmgs_core.c
+     patch  pvmgs/pvmgs_func.c
+     patch  pvmgs/pvmgsu_core.c
+     patch  src/HPPAMP/Makefile.shmem
+     patch  src/Makefile.aimk
+     patch  src/PGON/pvmdmimd.c
+     patch  src/global.h
+     patch  src/host.c
+     patch  src/lpvm.c
+     patch  src/lpvmcat.c
+     patch  src/lpvmgen.c
+     patch  src/lpvmmimd.c
+     patch  src/lpvmpack.c
+     patch  src/lpvmshmem.c
+     patch  src/pvmarchc.c
+     patch  src/pvmcruft.c
+     patch  src/pvmd.c
+     patch  src/pvmdshmem.c
+     patch  src/pvmshmem.c
+     patch  src/pvmshmem.h
+     patch  src/pvmumbuf.c
+     patch  src/startup.c
+     patch  src/waitc.c
+ what:
+     + contributed NCR AT&T 3/486 port, arch name ATT.
+     + contributed port to 803/486 running Solaris 2 (X86SOL2).
+     + new script $PVM_ROOT/lib/ipcfree to clean up shared memory segments.
+     + new misc/ directory to hold random examples, utilities and patches.
+     + new define NEEDFFS compiles in retrofit ffs().
+     + new pvmd -t flag for to test slave startup.
+     . RSHCOMMAND set for several arch's (RS6K RS6KMP SUN4SOL2 SUNMP)
+     . miscellaneous fixes for pure solaris machines (uname, rsh path, ...).
+     . small fixes to FREEBSD port (declarations and xdr_float, double routines).
+     . miscellaneous typos fixed in group server.
+     . PGON fix - spawned tasks now inherit environment correctly
+       (that of pvmd combined with parent task).
+     . fix to shared-memory pvmd - stale pages (from dead tasks) are skipped,
+       instead of hanging the input loop.
+     . fix to shared-memory libpvm - EINTR from semop() is ignored.
+     . fix to RS6KMP detection (now correctly checks number of processors).
+     . fix to message refragmentation code, bug caused messages from shared
+       memory task to task on another architecture to be corrupted.
+     . replies to task control messages are freed (small memory leak).
  patch #9
  version:
      3.3.8 -> 3.3.9
*** ../netlib/pvm3.3.9/patches/README	Tue Mar 14 09:57:08 1995
--- patches/README	Thu Nov  2 12:14:52 1995
***************
*** 1,5 ****
  
! PVM version 3.2 Patches Readme
  14 Mar 1995
  
  ________________________________________________________________________
--- 1,5 ----
  
! PVM version 3.3 Patches Readme
  14 Mar 1995
  
  ________________________________________________________________________
*** /dev/null	Fri Nov 10 16:56:01 1995
--- patches/README.339to10	Fri Nov 10 16:46:50 1995
***************
*** 0 ****
--- 1,17 ----
+ 
+ PVM version 3.3 Patch #10 Readme
+ 02 Nov 1995
+ 
+ ________________________________________________________________________
+ 
+ After applying patch 10 with the usual:
+ 
+     ; cd pvm3
+     ; patch -p0 < patches/pvm339to10
+ 
+ you should change the modes of new file lib/ipcfree:
+ 
+     ; chmod a+x lib/ipcfree
+ 
+ -b
+ 
*** ../netlib/pvm3.3.9/pvmgs/pvm_gstat.c	Wed May 17 11:53:06 1995
--- pvmgs/pvm_gstat.c	Thu Nov  2 10:49:51 1995
***************
*** 1,4 ****
! /* $Id: pvm_gstat.c,v 1.1 1995/05/17 15:52:48 manchek Exp $ */
  /*
     pvm_gstat - print the status of all groups held 
  */
--- 1,4 ----
! /* $Id: pvm_gstat.c,v 1.2 1995/11/02 15:49:38 manchek Exp $ */
  /*
     pvm_gstat - print the status of all groups held 
  */
***************
*** 7,13 ****
  #include "pvm3.h"
  #include "../src/pvmalloc.h"
  #include "pvmgsd.h"
! #define NEWMEM(p,n,t) if (p == (t *) NULL) PVM_FREE(p); p = (t *) PVM_ALLOC(n  * sizeof(t) ,"pvm_gstat")
  int
  main(argc, argv)
  int argc;
--- 7,13 ----
  #include "pvm3.h"
  #include "../src/pvmalloc.h"
  #include "pvmgsd.h"
! #define NEWMEM(p,n,t) if (p != (t *) NULL) PVM_FREE(p); p = (t *) PVM_ALLOC(n  * sizeof(t) ,"pvm_gstat")
  int
  main(argc, argv)
  int argc;
*** ../netlib/pvm3.3.9/pvmgs/pvmgs_core.c	Mon Jun 12 13:50:52 1995
--- pvmgs/pvmgs_core.c	Thu Nov  2 10:51:43 1995
***************
*** 1,4 ****
! /* $Id: pvmgs_core.c,v 1.2 1995/06/12 17:50:37 manchek Exp $ */
  /* This is the core of the group server. Everything is now dynamically
     allocated keep memory cost down and allow larger groups.  */
  /*
--- 1,4 ----
! /* $Id: pvmgs_core.c,v 1.3 1995/11/02 15:51:39 manchek Exp $ */
  /* This is the core of the group server. Everything is now dynamically
     allocated keep memory cost down and allow larger groups.  */
  /*
***************
*** 140,147 ****
                       fprintf(stderr, "Host characterization: \n");
                       for ( j=0; j < group->nhosts; j++)
                           fprintf(stderr, "host %x - %d procs, %x coord \n",
!                                    pvm_tidtohost(group->pcoord[i]), 
!                                    group->np_onhost[i], group->pcoord[i]); 
                   }
                   current = current->next;
              }
--- 140,147 ----
                       fprintf(stderr, "Host characterization: \n");
                       for ( j=0; j < group->nhosts; j++)
                           fprintf(stderr, "host %x - %d procs, %x coord \n",
!                                    pvm_tidtohost(group->pcoord[j]), 
!                                    group->np_onhost[j], group->pcoord[j]); 
                   }
                   current = current->next;
              }
*** ../netlib/pvm3.3.9/pvmgs/pvmgs_func.c	Fri Jun 16 11:42:58 1995
--- pvmgs/pvmgs_func.c	Thu Nov  2 10:53:39 1995
***************
*** 1,5 ****
  /* File: pvmgs_func.c - functions supported by pvmgs                       */
! /* $Id: pvmgs_func.c,v 1.3 1995/06/16 15:42:51 manchek Exp $      */ 
  
  #include <stdio.h>
  #include "pvm3.h"
--- 1,5 ----
  /* File: pvmgs_func.c - functions supported by pvmgs                       */
! /* $Id: pvmgs_func.c,v 1.4 1995/11/02 15:53:33 manchek Exp $      */ 
  
  #include <stdio.h>
  #include "pvm3.h"
***************
*** 36,47 ****
    
          /* copy the old array contents to the new array, initialize the    */
          /* new memory with the specified init value                        */
!         BCOPY(array, newarray, oldmax*sizeof(int));
          newvalue = newarray+oldmax;
          for (i = oldmax;  i < *maxelems; i++)
              *newvalue++ = init;
! 
!         PVM_FREE(array);
          return(newarray);
  }
  
--- 36,48 ----
    
          /* copy the old array contents to the new array, initialize the    */
          /* new memory with the specified init value                        */
!         if (oldmax > 0)
!         	BCOPY(array, newarray, oldmax*sizeof(int));
          newvalue = newarray+oldmax;
          for (i = oldmax;  i < *maxelems; i++)
              *newvalue++ = init;
! 		if (array != (int *) NULL)  /* initial array could be NULL */
!         	PVM_FREE(array);
          return(newarray);
  }
  
***************
*** 536,542 ****
          if (group->staticgroup == STATICDEAD) /* no collectives allowed on */
              return(PvmNoGroup);               /* a dead static group       */
          ntids = group->ntids;
!         tids = (int *) PVM_ALLOC(group->ntids * sizeof(int), "gs_tidlist()");
          for (i  = 0, cnt = 0; i < group->maxntids; i++)
          {
              if (group->tids[i] != -1)
--- 537,544 ----
          if (group->staticgroup == STATICDEAD) /* no collectives allowed on */
              return(PvmNoGroup);               /* a dead static group       */
          ntids = group->ntids;
!         if ( (tids = (int *) PVM_ALLOC(group->ntids * sizeof(int),
! 				 "gs_tidlist()")) == (int *) NULL ) return (PvmNoMem);
          for (i  = 0, cnt = 0; i < group->maxntids; i++)
          {
              if (group->tids[i] != -1)
*** ../netlib/pvm3.3.9/pvmgs/pvmgsu_core.c	Mon Jun 26 15:21:43 1995
--- pvmgs/pvmgsu_core.c	Thu Nov  2 10:55:22 1995
***************
*** 1,6 ****
  /*
   *	pvmgsu_core.c - Core group library routines  
! $Id: pvmgsu_core.c,v 1.4 1995/06/26 19:21:26 manchek Exp $
   * Revision 1.4  1994/11/07  21:09:38  manchek
   * include stdlib if available.
   * function prototypes for SCO.
--- 1,6 ----
  /*
   *	pvmgsu_core.c - Core group library routines  
! $Id: pvmgsu_core.c,v 1.5 1995/11/02 15:55:11 manchek Exp $
   * Revision 1.4  1994/11/07  21:09:38  manchek
   * include stdlib if available.
   * function prototypes for SCO.
***************
*** 559,569 ****
              DO_ERROR_RTN(info,"gs_cachegroup");
          if (len < 0)                  /* didn't get a valid groupname     */
              return(-1);
!         newname = (char *) PVM_ALLOC(sizeof(char)*(len + 1), "gs_cachegroup");
          if ( (info = pvm_upkstr(newname))  < 0  )
          {
              PVM_FREE(newname);
!             DO_ERROR_RTN(info, "gs_cachgroup");
          }
          sgroup = gs_group(newname, sgroup_list, ngroups, CREATE);
          if (sgroup != (GROUP_STRUCT_PTR) NULL)
--- 559,571 ----
              DO_ERROR_RTN(info,"gs_cachegroup");
          if (len < 0)                  /* didn't get a valid groupname     */
              return(-1);
!         if ( (newname = (char *) PVM_ALLOC(sizeof(char)*(len + 1),
!                     "gs_cachegroup") ) == (char *) NULL) 
! 			DO_ERROR_RTN(PvmNoMem,"gs_cachegroup");
          if ( (info = pvm_upkstr(newname))  < 0  )
          {
              PVM_FREE(newname);
!             DO_ERROR_RTN(info, "gs_cachegroup");
          }
          sgroup = gs_group(newname, sgroup_list, ngroups, CREATE);
          if (sgroup != (GROUP_STRUCT_PTR) NULL)
***************
*** 579,585 ****
                  DO_ERROR_RTN(info, "gs_cachegroup");
              }
              sgroup->tids = (int *) PVM_ALLOC(sgroup->maxntids*sizeof(int),
!                                                        caller);
              if (sgroup->tids == (int *) NULL)
                  gs_delete_group(newname, sgroup_list, ngroups);
              else
--- 581,587 ----
                  DO_ERROR_RTN(info, "gs_cachegroup");
              }
              sgroup->tids = (int *) PVM_ALLOC(sgroup->maxntids*sizeof(int),
!                                                        "gs_cachegroup");
              if (sgroup->tids == (int *) NULL)
                  gs_delete_group(newname, sgroup_list, ngroups);
              else
*** ../netlib/pvm3.3.9/src/HPPAMP/Makefile.shmem	Fri Jul  7 11:36:30 1995
--- src/HPPAMP/Makefile.shmem	Thu Nov  9 15:40:10 1995
***************
*** 10,16 ****
--- 10,19 ----
  #
  # Compatibility defines (usually in conf/*.def):
  #  FDSETPATCH      if system includes don't have fd_set stuff
+ #  HASERRORVARS    if errno, sys_nerr, sys_errlist already declared
  #  HASSTDLIB       if system has stdlib.h
+ #  NEEDENDIAN      to include <endian.h>
+ #  NEEDMENDIAN     to include <machine/endian.h>
  #  NOGETDTBLSIZ    if system doesn't have getdtablesize()
  #  NOREXEC         if system doesn't have rexec()
  #  NOSOCKOPT       if system doesn't have setsockopt() or it doesn't work
***************
*** 29,34 ****
--- 32,38 ----
  #
  # Options defines:
  #  CLUMP_ALLOC     allocates several data structures in big chunks
+ #  MCHECKSUM       to enable crc checksums on messages
  #  OVERLOADHOST    to allow different virtual machines to overlap on a host
  #  RSHNPLL=        for number of parallel rsh startups (default is 5)
  #  RSHTIMEOUT=     for rsh timeout other than default (60 sec)
***************
*** 251,256 ****
--- 255,262 ----
  pvmalloc.o: $(SDIR)/pvmalloc.h
  pvmarchc.o: $(SDIR)/protoglarp.h
  pvmarchc.o: $(SDIR)/pvmalloc.h
+ pvmcruft.o: $(SDIR)/../include/pvmsdpro.h
+ pvmcruft.o: $(SDIR)/ddpro.h
  pvmcruft.o: $(SDIR)/global.h
  pvmcruft.o: $(SDIR)/protoglarp.h
  pvmcruft.o: $(SDIR)/pvmalloc.h
*** ../netlib/pvm3.3.9/src/Makefile.aimk	Fri Sep  8 13:58:57 1995
--- src/Makefile.aimk	Thu Sep 21 12:07:20 1995
***************
*** 46,52 ****
  OPTIONS	=	-O -DCLUMP_ALLOC
  #OPTIONS	=	-g
  #OPTIONS	=	-g -DSTATISTICS
! #OPTIONS	=	-g -DUSE_PVM_ALLOC -DSTATISTICS -DTIMESTAMPLOG -DSANITY
  #OPTIONS	=	-p
  CFLAGS	=	$(OPTIONS) -I$(SDIR)/../include -DARCHCLASS=\"$(PVM_ARCH)\" -DIMA_$(PVM_ARCH) $(ARCHCFLAGS)
  
--- 46,53 ----
  OPTIONS	=	-O -DCLUMP_ALLOC
  #OPTIONS	=	-g
  #OPTIONS	=	-g -DSTATISTICS
! #OPTIONS	=	-O -DCLUMP_ALLOC -DUSE_PVM_ALLOC -DSTATISTICS -DTIMESTAMPLOG -DSANITY
! #OPTIONS	=	-g -DCLUMP_ALLOC -DUSE_PVM_ALLOC -DSTATISTICS -DTIMESTAMPLOG -DSANITY
  #OPTIONS	=	-p
  CFLAGS	=	$(OPTIONS) -I$(SDIR)/../include -DARCHCLASS=\"$(PVM_ARCH)\" -DIMA_$(PVM_ARCH) $(ARCHCFLAGS)
  
*** ../netlib/pvm3.3.9/src/PGON/pvmdmimd.c	Fri Jul 28 16:30:46 1995
--- src/PGON/pvmdmimd.c	Thu Nov  2 10:59:39 1995
***************
*** 96,101 ****
--- 96,104 ----
   *      deleted loclinput(), and merged loclinpkt() into pvmd.c
   *
  $Log: pvmdmimd.c,v $
+  * Revision 1.12  1995/11/02  15:59:01  manchek
+  * fixed so spawned tasks inherit pvmd environment plus parent task env
+  *
   * Revision 1.11  1995/07/28  20:30:38  manchek
   * pvmtxt should have been etext
   *
***************
*** 178,183 ****
--- 181,190 ----
  
  /* Global */
  
+ extern char **pvmcopyenv();
+ extern int pvmenvinsert();
+ extern int pvmfreeenv();
+ 
  extern char **environ;
  
  extern int debugmask;			/* from pvmd.c */
***************
*** 193,199 ****
  
  /* private */
  
! static char rcsid[] = "$Id: pvmdmimd.c,v 1.11 1995/07/28 20:30:38 manchek Exp $";
  static struct nodeset *busynodes;	/* active nodes; ordered by proc type */
  static char etext[512];			/* scratch for error log */
  static int ptypemask;			/* mask; we use these bits of ptype in tids */
--- 200,206 ----
  
  /* private */
  
! static char rcsid[] = "$Id: pvmdmimd.c,v 1.12 1995/11/02 15:59:01 manchek Exp $";
  static struct nodeset *busynodes;	/* active nodes; ordered by proc type */
  static char etext[512];			/* scratch for error log */
  static int ptypemask;			/* mask; we use these bits of ptype in tids */
***************
*** 384,389 ****
--- 391,397 ----
  {
      char path[MAXPATHLEN];
      struct stat sb;
+     char **cenv;           /* complete environment , pvmd's + PVM_EXPORTed*/
      char **ep, **eplist;
  	static int first = 1;
  	int j;
***************
*** 427,433 ****
  		for (j = 0; j < count; j++)
  			nodes[j] = sp->n_first + j;
  
! 		err = nx_loadve(nodes, nnodes, sp->n_ptype, pids, path, argv, envp);
  		if (err < count) {
  			sprintf(etext, "mpp_load() loaded only %d <%s>\n", err, path);
  			pvmlogerror(etext);
--- 435,446 ----
  		for (j = 0; j < count; j++)
  			nodes[j] = sp->n_first + j;
  
! 	/* copy the pvmd's environment, augment with what is passed to us */
! 		cenv = pvmcopyenv(environ);
! 		while (nenv > 0)
! 			pvmenvinsert(&cenv, envp[--nenv]);
! 		err = nx_loadve(nodes, nnodes, sp->n_ptype, pids, path, argv, cenv);
! 		pvmfreeenv(cenv); /* free the copy */
  		if (err < count) {
  			sprintf(etext, "mpp_load() loaded only %d <%s>\n", err, path);
  			pvmlogerror(etext);
*** ../netlib/pvm3.3.9/src/global.h	Fri Sep  8 13:58:58 1995
--- src/global.h	Thu Nov  2 11:00:40 1995
***************
*** 32,37 ****
--- 32,40 ----
   *	Generic includes.
   *
  $Log: global.h,v $
+  * Revision 1.20  1995/11/02  16:00:37  manchek
+  * version change
+  *
   * Revision 1.19  1995/09/05  19:28:49  manchek
   * version change
   *
***************
*** 94,100 ****
  
  /* release version */
  
! #define	PVM_VER	"3.3.9"
  
  /* UDPMAXLEN should be set to the largest UDP message length
     your system can handle. */
--- 97,103 ----
  
  /* release version */
  
! #define	PVM_VER	"3.3.10"
  
  /* UDPMAXLEN should be set to the largest UDP message length
     your system can handle. */
*** ../netlib/pvm3.3.9/src/host.c	Fri Jul 28 12:51:35 1995
--- src/host.c	Thu Nov  2 11:02:43 1995
***************
*** 32,37 ****
--- 32,40 ----
   *	Host table functions.
   *
  $Log: host.c,v $
+  * Revision 1.9  1995/11/02  16:01:49  manchek
+  * use NET_IF_IN_SYS if include/sys/net/if.h
+  *
   * Revision 1.8  1995/07/28  16:51:30  manchek
   * ifdef for UTS2
   *
***************
*** 69,75 ****
  #include <sys/time.h>
  #include <sys/socket.h>
  #include <netinet/in.h>
! #if	defined(IMA_E88K) || defined(IMA_UTS2)
  #include <sys/net/if.h>
  #else
  #include <net/if.h>
--- 72,78 ----
  #include <sys/time.h>
  #include <sys/socket.h>
  #include <netinet/in.h>
! #ifdef	NET_IF_IN_SYS
  #include <sys/net/if.h>
  #else
  #include <net/if.h>
***************
*** 120,126 ****
   **           **
   ***************/
  
! static char rcsid[] = "$Id: host.c,v 1.8 1995/07/28 16:51:30 manchek Exp $";
  static char pvmtxt[1024];			/* scratch space for error messages */
  
  
--- 123,129 ----
   **           **
   ***************/
  
! static char rcsid[] = "$Id: host.c,v 1.9 1995/11/02 16:01:49 manchek Exp $";
  static char pvmtxt[1024];			/* scratch space for error messages */
  
  
*** ../netlib/pvm3.3.9/src/lpvm.c	Fri Sep  8 13:58:58 1995
--- src/lpvm.c	Thu Nov  2 11:07:27 1995
***************
*** 32,37 ****
--- 32,42 ----
   *	Libpvm core for unix environment.
   *
  $Log: lpvm.c,v $
+  * Revision 1.32  1995/11/02  16:07:10  manchek
+  * added NEEDSENDIAN switch.
+  * must declare ptr to sys_errlist const in pvmlogperror for FREEBSD.
+  * free replies to control messages in mxfer
+  *
   * Revision 1.31  1995/09/06  17:37:24  manchek
   * aargh, forgot pvm_precv
   *
***************
*** 147,152 ****
--- 152,160 ----
  #ifdef NEEDENDIAN
  #include <endian.h>
  #endif
+ #ifdef NEEDSENDIAN
+ #include <sys/endian.h>
+ #endif
  #include <rpc/types.h>
  #include <rpc/xdr.h>
  #include <pvm3.h>
***************
*** 339,345 ****
   **           **
   ***************/
  
! static char rcsid[] = "$Id: lpvm.c,v 1.31 1995/09/06 17:37:24 manchek Exp $";
  static int debugmask = 0;				/* which debugging info */
  static int mxfersingle = 1;				/* mxfer returns after single frag */
  static char pvmtxt[512];				/* scratch for error log */
--- 347,353 ----
   **           **
   ***************/
  
! static char rcsid[] = "$Id: lpvm.c,v 1.32 1995/11/02 16:07:10 manchek Exp $";
  static int debugmask = 0;				/* which debugging info */
  static int mxfersingle = 1;				/* mxfer returns after single frag */
  static char pvmtxt[512];				/* scratch for error log */
***************
*** 396,402 ****
--- 404,414 ----
  pvmlogperror(s)
  	char *s;
  {
+ #ifdef	IMA_FREEBSD
+ 	const char *em;
+ #else
  	char *em;
+ #endif
  
  	em = ((errno >= 0 && errno < sys_nerr)
  		? sys_errlist[errno] : "Unknown Error");
***************
*** 1484,1491 ****
  	struct sockaddr_in sad;
  	int s;
  	struct ttpcb *pcbp;
! 	int tstk[100];				/* XXX aaigh! shouldn't be a stack */
  	int tstkp = 0;
  	char dummy[TDFRAGHDR+TTMSGHDR];	/* for inplace data */
  
  	if (tmout)
--- 1496,1504 ----
  	struct sockaddr_in sad;
  	int s;
  	struct ttpcb *pcbp;
! 	int freethis = 0;			/* (control) message came from stack */
  	int tstkp = 0;
+ 	int tstk[100];				/* XXX aaigh! shouldn't be a stack */
  	char dummy[TDFRAGHDR+TTMSGHDR];	/* for inplace data */
  
  	if (tmout)
***************
*** 1618,1623 ****
--- 1631,1637 ----
  							if (!(txpcbp = ttpcb_find(txup->ub_dst))
  							|| txpcbp->tt_state != TTOPEN)
  								txpcbp = topvmd;
+ 							freethis = 1;
  						}
  					}
  				}
***************
*** 1778,1783 ****
--- 1792,1799 ----
  						txcp = 0;
  						txfp = txfp->fr_link;
  						if (!txfp->fr_buf) {
+ 							if (freethis)
+ 								umbuf_free(txup->ub_mid);
  							if (tstkp > 0) {
  								txup = midtobuf(tstk[--tstkp]);
  								txfp = txup->ub_frag->fr_link;
***************
*** 1785,1790 ****
--- 1801,1807 ----
  								if (!(txpcbp = ttpcb_find(txup->ub_dst))
  								|| txpcbp->tt_state != TTOPEN)
  									txpcbp = topvmd;
+ 								freethis = 1;
  							} else
  								txfp = 0;
  						}
*** ../netlib/pvm3.3.9/src/lpvmcat.c	Fri Jul 28 12:04:05 1995
--- src/lpvmcat.c	Thu Nov  2 11:08:19 1995
***************
*** 32,37 ****
--- 32,40 ----
   *	Child task output collection.
   *
  $Log: lpvmcat.c,v $
+  * Revision 1.7  1995/11/02  16:08:12  manchek
+  * added NEEDSENDIAN switch
+  *
   * Revision 1.6  1995/07/28  16:04:05  manchek
   * switch endian includes on flag, not arch name
   *
***************
*** 60,65 ****
--- 63,71 ----
  #ifdef NEEDENDIAN
  #include <endian.h>
  #endif
+ #ifdef NEEDSENDIAN
+ #include <sys/endian.h>
+ #endif
  #include <rpc/types.h>
  #include <rpc/xdr.h>
  #ifdef	SYSVSTR
***************
*** 121,127 ****
   **           **
   ***************/
  
! static char rcsid[] = "$Id: lpvmcat.c,v 1.6 1995/07/28 16:04:05 manchek Exp $";
  static char pvmtxt[512];				/* scratch for error log */
  static struct tobuf *tobuflist = 0;
  static FILE *outlogff = 0;
--- 127,133 ----
   **           **
   ***************/
  
! static char rcsid[] = "$Id: lpvmcat.c,v 1.7 1995/11/02 16:08:12 manchek Exp $";
  static char pvmtxt[512];				/* scratch for error log */
  static struct tobuf *tobuflist = 0;
  static FILE *outlogff = 0;
*** ../netlib/pvm3.3.9/src/lpvmgen.c	Fri Jul 28 12:04:06 1995
--- src/lpvmgen.c	Thu Nov  2 11:09:53 1995
***************
*** 32,37 ****
--- 32,41 ----
   *	Libpvm generic functions.
   *
  $Log: lpvmgen.c,v $
+  * Revision 1.10  1995/11/02  16:09:32  manchek
+  * added NEEDSENDIAN switch.
+  * pass environment through spawn on PGON
+  *
   * Revision 1.9  1995/07/28  16:04:05  manchek
   * switch endian includes on flag, not arch name
   *
***************
*** 70,75 ****
--- 74,82 ----
  #ifdef NEEDENDIAN
  #include <endian.h>
  #endif
+ #ifdef NEEDSENDIAN
+ #include <sys/endian.h>
+ #endif
  #include <rpc/types.h>
  #include <rpc/xdr.h>
  #ifdef	SYSVSTR
***************
*** 127,133 ****
  
  static int def_match();
  
! static char rcsid[] = "$Id: lpvmgen.c,v 1.9 1995/07/28 16:04:05 manchek Exp $";
  static char pvmtxt[512];				/* scratch for error log */
  static int (*recv_match)() = def_match;
  
--- 134,140 ----
  
  static int def_match();
  
! static char rcsid[] = "$Id: lpvmgen.c,v 1.10 1995/11/02 16:09:32 manchek Exp $";
  static char pvmtxt[512];				/* scratch for error log */
  static int (*recv_match)() = def_match;
  
***************
*** 1408,1414 ****
  }
  
  
! #if	defined(IMA_PGON) || defined(IMA_I860) || defined(IMA_CM5)
  static int
  pvmgetenvars(ep)
  	char ***ep;
--- 1415,1421 ----
  }
  
  
! #if	defined(IMA_I860) || defined(IMA_CM5)
  static int
  pvmgetenvars(ep)
  	char ***ep;
***************
*** 1416,1422 ****
  	return 0;
  }
  
! #else	/*defined(IMA_PGON) || defined(IMA_I860) || defined(IMA_CM5)*/
  static int
  pvmgetenvars(ep)
  	char ***ep;
--- 1423,1429 ----
  	return 0;
  }
  
! #else	/*defined(IMA_I860) || defined(IMA_CM5)*/
  static int
  pvmgetenvars(ep)
  	char ***ep;
***************
*** 1457,1463 ****
  		return 0;
  	}
  }
! #endif	/*defined(IMA_PGON) || defined(IMA_I860) || defined(IMA_CM5)*/
  
  
  int
--- 1464,1470 ----
  		return 0;
  	}
  }
! #endif	/*defined(IMA_I860) || defined(IMA_CM5)*/
  
  
  int
*** ../netlib/pvm3.3.9/src/lpvmmimd.c	Fri Sep  8 13:58:58 1995
--- src/lpvmmimd.c	Thu Nov  2 11:12:30 1995
***************
*** 32,37 ****
--- 32,43 ----
   *	Libpvm core for MPP environment.
   *
  $Log: lpvmmimd.c,v $
+  * Revision 1.20  1995/11/02  16:12:23  manchek
+  * free replies to control messages in mxfer
+  *
+  * Revision 1.19  1995/11/02  16:11:15  manchek
+  * removed hdump()
+  *
   * Revision 1.18  1995/09/06  17:37:25  manchek
   * aargh, forgot pvm_precv
   *
***************
*** 239,245 ****
   **           **
   ***************/
  
! static char rcsid[] = "$Id: lpvmmimd.c,v 1.18 1995/09/06 17:37:25 manchek Exp $";
  static int debugmask = 0;				/* which debugging info */
  static char pvmtxt[512];				/* scratch for error log */
  static struct umbuf *rxfrag = 0;		/* not-assembled incm msgs */
--- 245,251 ----
   **           **
   ***************/
  
! static char rcsid[] = "$Id: lpvmmimd.c,v 1.20 1995/11/02 16:12:23 manchek Exp $";
  static int debugmask = 0;				/* which debugging info */
  static char pvmtxt[512];				/* scratch for error log */
  static struct umbuf *rxfrag = 0;		/* not-assembled incm msgs */
***************
*** 334,355 ****
  }
  
  
- hdump(p, n, pad)
- 	char *p;	/* bytes */
- 	int n;		/* length */
- 	char *pad;
- {
- 	int i;
- 	pad = pad ? pad : "";
- 	for (i = 0; n-- > 0; i = ++i & 15) {
- 		fprintf(stderr, "%s%02x%s",
- 			i ? "" : pad,
- 			0xff & *p++,
- 			n && i != 15 ? " " : "\n");
- 	}
- }
- 
- 
  /*  pvmmctl()
  *
  *   Entry points for libpvm control messages.
--- 340,345 ----
***************
*** 626,631 ****
--- 616,622 ----
  									/* reply to sender */
  									node_send(txup, txfp, txup->ub_dst, 
  										txup->ub_cod);
+ 								umbuf_free(sbf); 
          	            	}
  						}
  #ifdef	MCHECKSUM
*** ../netlib/pvm3.3.9/src/lpvmpack.c	Fri Sep  8 13:58:58 1995
--- src/lpvmpack.c	Thu Nov  2 11:13:22 1995
***************
*** 32,37 ****
--- 32,40 ----
   *	Typed packing/unpacking, message buffer manip.
   *
  $Log: lpvmpack.c,v $
+  * Revision 1.12  1995/11/02  16:13:16  manchek
+  * added NEEDSENDIAN switch
+  *
   * Revision 1.11  1995/09/05  19:17:03  manchek
   * fp sometimes wasn't set in enc_xdr_init.
   * overflow test was wrong in enc_xdr_long
***************
*** 77,82 ****
--- 80,88 ----
  #ifdef NEEDENDIAN
  #include <endian.h>
  #endif
+ #ifdef NEEDSENDIAN
+ #include <sys/endian.h>
+ #endif
  #include <rpc/types.h>
  #include <rpc/xdr.h>
  #include <ctype.h>
***************
*** 121,127 ****
   **           **
   ***************/
  
! static char rcsid[] = "$Id: lpvmpack.c,v 1.11 1995/09/05 19:17:03 manchek Exp $";
  static char pvmtxt[512];				/* scratch for error log */
  
  
--- 127,133 ----
   **           **
   ***************/
  
! static char rcsid[] = "$Id: lpvmpack.c,v 1.12 1995/11/02 16:13:16 manchek Exp $";
  static char pvmtxt[512];				/* scratch for error log */
  
  
*** ../netlib/pvm3.3.9/src/lpvmshmem.c	Fri Sep  8 13:58:58 1995
--- src/lpvmshmem.c	Fri Nov 10 16:37:58 1995
***************
*** 32,37 ****
--- 32,43 ----
   *	Libpvm core for MPP environment.
   *
  $Log: lpvmshmem.c,v $
+  * Revision 1.39  1995/11/10  21:37:46  manchek
+  * check for EINTR from semop in peer_wait
+  *
+  * Revision 1.38  1995/11/02  16:17:20  manchek
+  * free replies to control messages in mxfer
+  *
   * Revision 1.37  1995/09/08  17:26:02  manchek
   * aargh forgot semicolon
   *
***************
*** 337,343 ****
   **           **
   ***************/
  
! static char rcsid[] = "$Id: lpvmshmem.c,v 1.37 1995/09/08 17:26:02 manchek Exp $";
  static char pvmtxt[512];				/* scratch for error log */
  static struct umbuf *rxfrag = 0;		/* not-assembled incm msgs */
  static struct frag *rxbuf;				/* buffer for incoming packets */
--- 343,349 ----
   **           **
   ***************/
  
! static char rcsid[] = "$Id: lpvmshmem.c,v 1.39 1995/11/10 21:37:46 manchek Exp $";
  static char pvmtxt[512];				/* scratch for error log */
  static struct umbuf *rxfrag = 0;		/* not-assembled incm msgs */
  static struct frag *rxbuf;				/* buffer for incoming packets */
***************
*** 538,547 ****
  			pvmlogerror(pvmtxt);
  		}
  		if (semop(mysemid, &sops, 1) == -1) {
! 			sprintf(pvmtxt, "peer_wait(): Error waiting for semop id = %d",
! 					mysemid);
! 			pvmlogperror(pvmtxt);
! 			return -1;
  		}
  		else if (debugmask & PDMSEM) {
  			sprintf(pvmtxt, "peer_wait(): Processing Event on semop id = %d\n",
--- 544,555 ----
  			pvmlogerror(pvmtxt);
  		}
  		if (semop(mysemid, &sops, 1) == -1) {
! 			if (errno != EINTR) {
! 				sprintf(pvmtxt, "peer_wait(): Error waiting for semop id = %d",
! 						mysemid);
! 				pvmlogperror(pvmtxt);
! 				return -1;
! 			}
  		}
  		else if (debugmask & PDMSEM) {
  			sprintf(pvmtxt, "peer_wait(): Processing Event on semop id = %d\n",
***************
*** 677,686 ****
  	int loopcount = 0;
  	struct msgboxhdr *inbp;		/* incoming box */
  	struct timeval tnow, tstop;
- 	int tstk[100];				/* XXX shouldn't be a stack */
- 	int tstkp = 0;
  	int sbf;					/* reply to control message */
  	int cc;
  
  	/* XXX do we really have to do this? */
  	if ((dtid == TIDPVMD && code == TM_MCA) || dtid == TIDGID)
--- 685,695 ----
  	int loopcount = 0;
  	struct msgboxhdr *inbp;		/* incoming box */
  	struct timeval tnow, tstop;
  	int sbf;					/* reply to control message */
  	int cc;
+ 	int freethis = 0;			/* (control) message came from stack */
+ 	int tstkp = 0;
+ 	int tstk[100];				/* XXX shouldn't be a stack */
  
  	/* XXX do we really have to do this? */
  	if ((dtid == TIDPVMD && code == TM_MCA) || dtid == TIDGID)
***************
*** 740,745 ****
--- 749,755 ----
  					code = txup->ub_cod;
  					txfp = txup->ub_frag->fr_link;
  					txfp = txfp->fr_buf ? txfp : 0;
+ 					freethis = 1;
  				}
  			}
  		}
***************
*** 750,755 ****
--- 760,767 ----
  			if (cc) {
  				txfp = txfp->fr_link;
  				if (!txfp->fr_buf) {
+ 					if (freethis)
+ 						umbuf_free(txup->ub_mid);
  					if (tstkp > 0) {
  						txup = midtobuf(tstk[--tstkp]);
  						dtid = txup->ub_dst;
***************
*** 756,761 ****
--- 768,774 ----
  						code = txup->ub_cod;
  						txfp = txup->ub_frag->fr_link;
  						txfp = txfp->fr_buf ? txfp : 0;
+ 						freethis = 1;
  					} else
  						txfp = 0;
  				}
*** ../netlib/pvm3.3.9/src/pvmarchc.c	Fri Jul 28 18:56:59 1995
--- src/pvmarchc.c	Thu Nov  2 11:18:28 1995
***************
*** 32,37 ****
--- 32,40 ----
   *	Architecture classification.  Used to be archcode.c
   *
  $Log: pvmarchc.c,v $
+  * Revision 1.9  1995/11/02  16:18:12  manchek
+  * added X86SOL2 and ATT to arch array
+  *
   * Revision 1.8  1995/07/28  22:56:53  manchek
   * mooshed around a bit
   *
***************
*** 84,90 ****
  	struct nl *nl_next;
  };
  
! static char rcsid[] = "$Id: pvmarchc.c,v 1.8 1995/07/28 22:56:53 manchek Exp $";
  static char pvmtxt[512];				/* scratch for error log */
  static struct nl *morearches = 0;
  static int lastarch = 0;
--- 87,93 ----
  	struct nl *nl_next;
  };
  
! static char rcsid[] = "$Id: pvmarchc.c,v 1.9 1995/11/02 16:18:12 manchek Exp $";
  static char pvmtxt[512];				/* scratch for error log */
  static struct nl *morearches = 0;
  static int lastarch = 0;
***************
*** 145,150 ****
--- 148,155 ----
  	{"PMAX", 12},
  	{"SCO", 12},
  	{"SYMM", 12},
+ 	{"X86SOL2", 12},
+ 	{"ATT", 12},
  
  	{"I860", 13},
  	{"PGON", 13},
*** ../netlib/pvm3.3.9/src/pvmcruft.c	Wed Jul 19 17:26:47 1995
--- src/pvmcruft.c	Thu Nov  2 11:21:48 1995
***************
*** 32,37 ****
--- 32,42 ----
   *	Missing links and other wonk.
   *
  $Log: pvmcruft.c,v $
+  * Revision 1.10  1995/11/02  16:21:34  manchek
+  * made pvmhdump write to pvm log.
+  * new switch NEEDSFFS for ffs.
+  * added pvmcopyenv, pvmenvinsert and pvmfreeenv
+  *
   * Revision 1.9  1995/07/19  21:26:27  manchek
   * new function pvmnametag converts message tag to name or decimal string
   *
***************
*** 102,108 ****
   **           **
   ***************/
  
! static char rcsid[] = "$Id: pvmcruft.c,v 1.9 1995/07/19 21:26:27 manchek Exp $";
  
  
  int
--- 107,113 ----
   **           **
   ***************/
  
! static char rcsid[] = "$Id: pvmcruft.c,v 1.10 1995/11/02 16:21:34 manchek Exp $";
  
  
  int
***************
*** 201,207 ****
  
  #endif /*NOGETDTBLSIZ*/
  
! #if defined(IMA_TITN) || defined(I860_NODE) || defined(I860_SRM) || defined(IMA_SCO)
  int
  ffs(x)
  	int x;
--- 206,212 ----
  
  #endif /*NOGETDTBLSIZ*/
  
! #ifdef	NEEDSFFS
  int
  ffs(x)
  	int x;
***************
*** 283,288 ****
--- 288,402 ----
  }
  
  
+ /*	pvmcopyenv()
+ *
+ *	Make copy of an environment list (null-terminated vector of strings).
+ *	This is just like environ, but we own all the strings.
+ *	Can also be used to create an empty list, by passing a null pointer.
+ *
+ *	Returns pointer to environment or NULL if malloc fails.
+ */
+ 
+ char **
+ pvmcopyenv(anyep)
+ 	char **anyep;		/* old environment to copy, or NULL */
+ {
+ 	char **newep;
+ 	int i, n;
+ 
+ 	if (anyep) {
+ 		for (n = 0; anyep[n]; n++) ;
+ 		if (newep = TALLOC(n + 1, char *, "env")) {
+ 			newep[n] = 0;
+ 			for (i = 0; i < n; i++) {
+ 				if (!(newep[i] = STRALLOC(anyep[i]))) {
+ 					while (i-- > 0)
+ 						PVM_FREE(newep[i]);
+ 					PVM_FREE(newep);
+ 					newep = 0;
+ 					break;
+ 				}
+ 			}
+ 		}
+ 
+ 	} else {
+ 		if (newep = TALLOC(1, char *, "env"))
+ 			newep[0] = 0;
+ 	}
+ 	return newep;
+ }
+ 
+ 
+ /*	pvmenvinsert()
+ *
+ *	Put a copy of a string into an environment list (made by pvmcopyenv).
+ *	List must be one of ours, since we malloc and free the strings.
+ *
+ *	Returns zero or success, or -1 if malloc fails.
+ *	May update pointer to environment on return.
+ */
+ 
+ int
+ pvmenvinsert(anep, s)
+ 	char ***anep;		/* environment pointer, may change (NOT environ) */
+ 	char *s;			/* string of form "NAME=Value" */
+ {
+ 	char **ep;
+ 	char **newep;
+ 	char *p;
+ 	int l;						/* length of env var name or env */
+ 
+ 	newep = *anep;
+ 
+ 	if (!s || !(p = CINDEX(s, '=')))
+ 		return -1;
+ 	l = p - s + 1;			/* must include the '=' */
+ 
+ 	/* search environ for name */
+ 
+ 	for (ep = newep; *ep; ep++)
+ 		if (!strncmp(*ep, s, l))
+ 			break;
+ 
+ 	if (*ep) {				/* already there, replace it */
+ 		PVM_FREE(*ep);
+ 		*ep = STRALLOC(s);
+ 
+ 	} else {				/* not there, must extend environ */
+ 
+ 	/* length needed is? */
+ 
+ 		for (l = 2, ep = newep; *ep; l++, ep++);
+ 
+ 		if (!(newep = TREALLOC((char *)newep, l, char *)))
+ 			return -1;
+ 
+ 		newep[l - 2] = STRALLOC(s);
+ 		newep[l - 1] = 0;
+ 		*anep = newep;
+ 	}
+ 	return 0;
+ }
+ 
+ 
+ /*	pvmfreeenv()
+ *
+ *	Free an environment list (made by pvmcopyenv).
+ */
+ 
+ int
+ pvmfreeenv(anep)
+ 	char **anep;
+ {
+ 	char **p;
+ 
+ 	for (p = anep; *p; p++)
+ 		PVM_FREE(*p);
+ 	PVM_FREE(anep);
+ 	return 0;
+ }
+ 
+ 
  /*	pvmxtoi()
  *
  *	Yet another version of ascii hex to integer
***************
*** 377,395 ****
  #endif	/*NOTMPNAM*/
  
  
! pvmhdump(p, n, pad)
! 	char *p;	/* bytes */
! 	int n;		/* length */
! 	char *pad;
  {
! 	int i;
  	pad = pad ? pad : "";
  	for (i = 0; n-- > 0; i = (i + 1) & 15) {
! 		fprintf(stderr, "%s%02x%s",
! 			i ? "" : pad,
! 			0xff & *p++,
! 			n && i != 15 ? " " : "\n");
  	}
  	return 0;
  }
  
--- 491,533 ----
  #endif	/*NOTMPNAM*/
  
  
! pvmhdump(cp, n, pad)
! 	char *cp;		/* bytes */
! 	int n;			/* length */
! 	char *pad;		/* tag string */
  {
! 	static char *buf = 0;
! 	static int bufl = 0;
! 
! 	int i, l;
! 	char *r;
! 
  	pad = pad ? pad : "";
+ 	l = strlen(pad) + 50;
+ 	if (l > bufl) {
+ 		if (buf)
+ 			PVM_FREE(buf);
+ 		if (!(buf = TALLOC(l, char, "hdump"))) {
+ 			bufl = 0;
+ 			pvmlogerror("pvmhdump() malloc failed\n");
+ 			return 1;
+ 		}
+ 		bufl = l;
+ 	}
+ 
+ 	r = buf;
  	for (i = 0; n-- > 0; i = (i + 1) & 15) {
! 		sprintf(r, "%s%02x",
! 			i ? " " : pad,
! 			0xff & *cp++);
! 		r += strlen(r);
! 		if (!n || i == 15) {
! 			strcpy(r, "\n");
! 			pvmlogerror(buf);
! 			r = buf;
! 		}
  	}
+ 
  	return 0;
  }
  
*** ../netlib/pvm3.3.9/src/pvmd.c	Fri Sep  8 13:58:58 1995
--- src/pvmd.c	Thu Nov  2 11:29:38 1995
***************
*** 32,37 ****
--- 32,42 ----
   *	Mr. pvm daemon.
   *
  $Log: pvmd.c,v $
+  * Revision 1.40  1995/11/02  16:29:24  manchek
+  * added -t flag for test mode.
+  * put back save under packet header in netoutput.
+  * refragment in pkt_to_host now handles message header correctly
+  *
   * Revision 1.39  1995/09/05  19:22:07  manchek
   * forgot ifdef for SP2MPI
   *
***************
*** 340,346 ****
   **           **
   ***************/
  
! static char rcsid[] = "$Id: pvmd.c,v 1.39 1995/09/05 19:22:07 manchek Exp $";
  static struct deaddata *deads = 0;	/* circ queue of dead task data */
  static char pvmtxt[512];		/* scratch for error log */
  static int ndead = 0;			/* len of deads */
--- 345,351 ----
   **           **
   ***************/
  
! static char rcsid[] = "$Id: pvmd.c,v 1.40 1995/11/02 16:29:24 manchek Exp $";
  static struct deaddata *deads = 0;	/* circ queue of dead task data */
  static char pvmtxt[512];		/* scratch for error log */
  static int ndead = 0;			/* len of deads */
***************
*** 361,369 ****
  	int argc;
  	char **argv;
  {
! 	int i, j, ac;
  	char *name = "";
  	struct passwd *pe;
  	char buf[128];
  
  	/* make sure 0, 1, 2 are in use */
--- 366,376 ----
  	int argc;
  	char **argv;
  {
! 	int i, j;
  	char *name = "";
  	struct passwd *pe;
+ 	int testmode = 0;
+ 	struct timeval tnow;
  	char buf[128];
  
  	/* make sure 0, 1, 2 are in use */
***************
*** 410,416 ****
  	mpp_setmtu();
  #endif
  
! 	for (i = j = ac = 1; i < argc; i++) {
  		if (argv[i][0] == '-') {
  			switch (argv[i][1]) {
  
--- 417,423 ----
  	mpp_setmtu();
  #endif
  
! 	for (i = j = 1; i < argc; i++) {
  		if (argv[i][0] == '-') {
  			switch (argv[i][1]) {
  
***************
*** 424,445 ****
  
  			case 'S':
  				argv[j++] = argv[i];
- 				ac++;
  			case 's':
  				slavemode = 1;
  				break;
  
  			default:
  				argv[j++] = argv[i];
- 				ac++;
  			}
  
  		} else {
  			argv[j++] = argv[i];
- 			ac++;
  		}
  	}
! 	argc = ac;
  
  	if (debugmask) {
  		sprintf(pvmtxt, "version %s\n", PVM_VER);
--- 431,453 ----
  
  			case 'S':
  				argv[j++] = argv[i];
  			case 's':
  				slavemode = 1;
  				break;
  
+ 			case 't':
+ 				testmode = 1;
+ 				break;
+ 
  			default:
  				argv[j++] = argv[i];
  			}
  
  		} else {
  			argv[j++] = argv[i];
  		}
  	}
! 	argc = j;
  
  	if (debugmask) {
  		sprintf(pvmtxt, "version %s\n", PVM_VER);
***************
*** 458,463 ****
--- 466,483 ----
  		}
  		name = buf;
  	}
+ 	if (testmode) {
+ 		gettimeofday(&tnow, (struct timezone*)0);
+ 		sprintf(pvmtxt, "version %s ddpro %d tdpro %d sdpro %d\n",
+ 				PVM_VER, DDPROTOCOL, TDPROTOCOL, SDPROTOCOL);
+ 		pvmlogerror(pvmtxt);
+ 		pvmlogerror(ctime(&tnow.tv_sec));
+ 		for (i = 0; i < argc; i++) {
+ 			sprintf(pvmtxt, "argv[%d]=\"%s\"\n", i, argv[i]);
+ 			pvmlogerror(pvmtxt);
+ 		}
+ 		exit(0);
+ 	}
  	if (slavemode)					/* slave pvmd */
  		slave_config(name, argc, argv);
  
***************
*** 1320,1325 ****
--- 1340,1346 ----
  	char *cp;
  	int len;
  	int cc;
+ 	char dummy[DDFRAGHDR];
  
  /*
  	len = 0;
***************
*** 1375,1380 ****
--- 1396,1407 ----
  		}
  		cp -= DDFRAGHDR;
  		len += DDFRAGHDR;
+ 
+ 	/*
+ 	* save under packet header, because databuf may be shared.
+ 	* we don't worry about message header, because it's only at the head.
+ 	*/
+ 		BCOPY(cp, dummy, sizeof(dummy));
  		if (cp < pp->pk_buf) {
  			pvmlogerror("netoutput() no headroom for packet header\n");
  			return 0;
***************
*** 1409,1415 ****
  #endif
  			) {
  				pvmlogperror("netoutput() sendto");
! #if defined(IMA_SUN4SOL2) || defined(IMA_SUNMP) || defined(IMA_UXPM)
  	/* life, don't talk to me about life... */
  				if (errno == ECHILD)
  					pvmlogerror("this message brought to you by solaris\n");
--- 1436,1442 ----
  #endif
  			) {
  				pvmlogperror("netoutput() sendto");
! #if defined(IMA_SUN4SOL2) || defined(IMA_X86SOL2) || defined(IMA_SUNMP) || defined(IMA_UXPM)
  	/* life, don't talk to me about life... */
  				if (errno == ECHILD)
  					pvmlogerror("this message brought to you by solaris\n");
***************
*** 1424,1429 ****
--- 1451,1458 ----
  			stats.sdok++;
  #endif
  
+ 		BCOPY(dummy, cp, sizeof(dummy));	/* restore under header */
+ 
  	/*
  	* set timer for next retry
  	*/
***************
*** 2292,2297 ****
--- 2321,2333 ----
  
  	if (pp->pk_len == TDFRAGHDR) {
  		if (m > pp->pk_max - (pp->pk_dat - pp->pk_buf)) {
+ 			if (!(tp->t_flag & TF_CONN)) {
+ 				sprintf(pvmtxt,
+ 					"loclinput() unconnected task sends frag length %d (ha)\n",
+ 					m);
+ 				pvmlogerror(pvmtxt);
+ 				return -1;
+ 			}
  			if (DDFRAGHDR > TDFRAGHDR) {
  				pp2 = pk_new(m + DDFRAGHDR - TDFRAGHDR);
  				pp2->pk_dat += DDFRAGHDR - TDFRAGHDR;
***************
*** 3074,3079 ****
--- 3110,3118 ----
  *	If data plus header length is greater than host mtu,
  *	refragment into >1 pkts.
  *
+ *	We have to pay special attention to the FFSOM packet - make it
+ *	shorter so there's room to prepend the message header later.
+ *
  *	If send window to host has room, push packet to opq.
  */
  
***************
*** 3082,3088 ****
  	struct hostd *hp;
  	struct pkt *pp;
  {
! 	int mmtu = hp->hd_mtu < ourudpmtu ? hp->hd_mtu : ourudpmtu;
  
  	pp->pk_flag = (pp->pk_flag & (FFSOM|FFEOM)) | FFDAT;
  	if (debugmask & PDMPACKET) {
--- 3121,3128 ----
  	struct hostd *hp;
  	struct pkt *pp;
  {
! 	int maxl = (hp->hd_mtu < ourudpmtu ? hp->hd_mtu : ourudpmtu) - DDFRAGHDR;
! 	int llim = pp->pk_flag & FFSOM ? maxl - TTMSGHDR : maxl;
  
  	pp->pk_flag = (pp->pk_flag & (FFSOM|FFEOM)) | FFDAT;
  	if (debugmask & PDMPACKET) {
***************
*** 3091,3102 ****
  		pvmlogerror(pvmtxt);
  	}
  
! 	if (pp->pk_len + DDFRAGHDR <= mmtu) {
  		LISTPUTBEFORE(hp->hd_txq, pp, pk_link, pk_rlink);
  
  	} else {
  		struct pkt *pp2;
- 		int lim = mmtu - DDFRAGHDR;
  		char *cp = pp->pk_dat;
  		int togo;
  		int n;
--- 3131,3141 ----
  		pvmlogerror(pvmtxt);
  	}
  
! 	if (pp->pk_len <= llim) {
  		LISTPUTBEFORE(hp->hd_txq, pp, pk_link, pk_rlink);
  
  	} else {
  		struct pkt *pp2;
  		char *cp = pp->pk_dat;
  		int togo;
  		int n;
***************
*** 3104,3114 ****
  		int fe = pp->pk_flag & FFEOM;
  
  		for (togo = pp->pk_len; togo > 0; togo -= n) {
! 			n = min(togo, lim);
! /*
! 			sprintf(pvmtxt, "pkt_to_host() refrag len %d\n", n);
! 			pvmlogerror(pvmtxt);
! */
  #ifdef	STATISTICS
  			stats.refrag++;
  #endif
--- 3143,3153 ----
  		int fe = pp->pk_flag & FFEOM;
  
  		for (togo = pp->pk_len; togo > 0; togo -= n) {
! 			n = min(togo, llim);
! 			if ((debugmask & PDMPACKET) && togo != pp->pk_len) {
! 				sprintf(pvmtxt, "pkt_to_host() refrag len %d\n", n);
! 				pvmlogerror(pvmtxt);
! 			}
  #ifdef	STATISTICS
  			stats.refrag++;
  #endif
***************
*** 3119,3124 ****
--- 3158,3164 ----
  				ff |= fe;
  			pp2->pk_flag = ff | FFDAT;
  			ff = 0;
+ 			llim = maxl;
  			pp2->pk_cod = pp->pk_cod;
  			pp2->pk_enc = pp->pk_enc;
  			pp2->pk_wid = pp->pk_wid;
***************
*** 3250,3256 ****
  
  	} else {
  		struct pkt *pp2;
! 		int lim = ourudpmtu - DDFRAGHDR;
  		char *cp = pp->pk_dat;
  		int togo;
  		int n;
--- 3290,3296 ----
  
  	} else {
  		struct pkt *pp2;
! 		int maxl = ourudpmtu - DDFRAGHDR;
  		char *cp = pp->pk_dat;
  		int togo;
  		int n;
***************
*** 3258,3264 ****
  		int fe = pp->pk_flag & FFEOM;
  
  		for (togo = pp->pk_len; togo > 0; togo -= n) {
! 			n = min(togo, lim);
  			sprintf(pvmtxt, "pkt_to_task() refrag len %d\n", n);
  			pvmlogerror(pvmtxt);
  			pp2 = pk_new(0);
--- 3298,3304 ----
  		int fe = pp->pk_flag & FFEOM;
  
  		for (togo = pp->pk_len; togo > 0; togo -= n) {
! 			n = min(togo, maxl);
  			sprintf(pvmtxt, "pkt_to_task() refrag len %d\n", n);
  			pvmlogerror(pvmtxt);
  			pp2 = pk_new(0);
*** ../netlib/pvm3.3.9/src/pvmdshmem.c	Fri Sep  8 13:58:58 1995
--- src/pvmdshmem.c	Thu Nov  2 11:31:38 1995
***************
*** 32,39 ****
   * Shared-memory MPP interface.
   *
  $Log: pvmdshmem.c,v $
!  * Revision 1.19  1995/09/05  19:24:05  manchek
!  * mpp_input copies all pages for now (in case sender task exits)
   *
   * Revision 1.19  1995/09/05  19:24:05  manchek
   * mpp_input copies all pages for now (in case sender task exits)
--- 32,39 ----
   * Shared-memory MPP interface.
   *
  $Log: pvmdshmem.c,v $
!  * Revision 1.20  1995/11/02  16:31:23  manchek
!  * skip over stale packets from dead tasks in mpp_input
   *
   * Revision 1.19  1995/09/05  19:24:05  manchek
   * mpp_input copies all pages for now (in case sender task exits)
***************
*** 180,186 ****
   **           **
   ***************/
  
! static char rcsid[] = "$Id: pvmdshmem.c,v 1.19 1995/09/05 19:24:05 manchek Exp $";
  static char pvmtxt[512];		/* scratch for error log */
  static int inboxsz = 0;			/* size of incoming message buffer */
  static struct pkt *ovfpkts = 0;	/* packets waiting to be delivered */
--- 180,186 ----
   **           **
   ***************/
  
! static char rcsid[] = "$Id: pvmdshmem.c,v 1.20 1995/11/02 16:31:23 manchek Exp $";
  static char pvmtxt[512];		/* scratch for error log */
  static int inboxsz = 0;			/* size of incoming message buffer */
  static struct pkt *ovfpkts = 0;	/* packets waiting to be delivered */
***************
*** 501,507 ****
  		if (!(pe = peer_conn(sdr, (int *)0)) || pe == (struct peer *)-1L) {
  			sprintf(pvmtxt, "mpp_input() can't connect to sender t%x\n", sdr);
  			pvmlogerror(pvmtxt);
! 			return;
  		}
  		cp = pe->p_buf + INBOXPAGE*pgsz + inmsgs[next].ph_dat;
  		buf = cp - (inmsgs[next].ph_dat & (pgsz-1)) + PVMPAGEHDR;
--- 501,507 ----
  		if (!(pe = peer_conn(sdr, (int *)0)) || pe == (struct peer *)-1L) {
  			sprintf(pvmtxt, "mpp_input() can't connect to sender t%x\n", sdr);
  			pvmlogerror(pvmtxt);
! 			continue;
  		}
  		cp = pe->p_buf + INBOXPAGE*pgsz + inmsgs[next].ph_dat;
  		buf = cp - (inmsgs[next].ph_dat & (pgsz-1)) + PVMPAGEHDR;
*** ../netlib/pvm3.3.9/src/pvmshmem.c	Fri Sep  8 13:58:59 1995
--- src/pvmshmem.c	Fri Nov 10 16:38:36 1995
***************
*** 32,37 ****
--- 32,43 ----
   *  Shared-memory stuff.
   *
  $Log: pvmshmem.c,v $
+  * Revision 1.21  1995/11/02  16:33:04  manchek
+  * peer_conn returns -1 if peer has disconnected
+  *
+  * Revision 1.21  1995/11/02  16:33:04  manchek
+  * peer_conn returns -1 if peer has disconnected
+  *
   * Revision 1.20  1995/09/07  17:38:27  manchek
   * Add __synch() when releasing lock.
   *
***************
*** 156,162 ****
   **           **
   ***************/
  
! static char rcsid[] = "$Id: pvmshmem.c,v 1.20 1995/09/07 17:38:27 manchek Exp $";
  static char pvmtxt[512];			/* scratch for error log */
  static int nxtpage = 0;				/* next free page in outgoing msg buf */
  
--- 162,168 ----
   **           **
   ***************/
  
! static char rcsid[] = "$Id: pvmshmem.c,v 1.21 1995/11/02 16:33:04 manchek Exp $";
  static char pvmtxt[512];			/* scratch for error log */
  static int nxtpage = 0;				/* next free page in outgoing msg buf */
  
***************
*** 339,345 ****
  *	Attach peer's message buffer.
  *	Returns pointer to peer struct,
  *	Else 0 if peer isn't ready to receive yet
! *	Or  -1 if peer can't be contacted via shared memory.
  */
  
  struct peer *
--- 345,351 ----
  *	Attach peer's message buffer.
  *	Returns pointer to peer struct,
  *	Else 0 if peer isn't ready to receive yet
! *	Or  -1 if peer can't be contacted via shared memory or has disconnected.
  */
  
  struct peer *
***************
*** 353,360 ****
  	if (new_connection)
  		*new_connection = 0;
  	for (pp = peers->p_link; pp != peers; pp = pp->p_link) {
! 		if (pp->p_tid == tid)	/* already connected */
! 			return (pp->p_buf ? pp : (struct peer *)-1L);
  	/*
  	* test p_buf in case we're in the process of destroying this peer struct
  	*/
--- 359,370 ----
  	if (new_connection)
  		*new_connection = 0;
  	for (pp = peers->p_link; pp != peers; pp = pp->p_link) {
! 		if (pp->p_tid == tid) {		/* already connected */
! 			if (pp->p_exited || !pp->p_buf)
! 				return ((struct peer *)-1L);
! 			else
! 				return pp;
! 		}
  	/*
  	* test p_buf in case we're in the process of destroying this peer struct
  	*/
*** ../netlib/pvm3.3.9/src/pvmshmem.h	Mon Jul 24 14:30:09 1995
--- src/pvmshmem.h	Thu Nov  9 15:43:00 1995
***************
*** 29,34 ****
--- 29,37 ----
   *  pvmshmem.h
   *
  $Log: pvmshmem.h,v $
+  * Revision 1.13  1995/11/09  20:42:49  manchek
+  * use add_then_test instead of test_then_add (SGI)
+  *
   * Revision 1.12  1995/07/24  18:29:56  manchek
   * added message header fields to shmpkhdr
   *
***************
*** 207,213 ****
  #define PAGEINITLOCK(lp)	(*(lp) = 0)
  #define PAGELOCK(lp)		while (test_and_set(lp, 1L)) ;
  #define PAGEUNLOCK(lp)		test_and_set(lp, 0L)
! #define	TEST_ADD(addr,inc)	test_then_add(addr, (long)inc)
  #define	PVMPAGEHDR			sizeof(struct shmpghdr)
  #endif /*IMA_SGIMP || IMA_SGIMP64*/
  
--- 210,216 ----
  #define PAGEINITLOCK(lp)	(*(lp) = 0)
  #define PAGELOCK(lp)		while (test_and_set(lp, 1L)) ;
  #define PAGEUNLOCK(lp)		test_and_set(lp, 0L)
! #define	TEST_ADD(addr,inc)	add_then_test(addr, (long)inc)
  #define	PVMPAGEHDR			sizeof(struct shmpghdr)
  #endif /*IMA_SGIMP || IMA_SGIMP64*/
  
*** ../netlib/pvm3.3.9/src/pvmumbuf.c	Tue Jul 18 13:02:29 1995
--- src/pvmumbuf.c	Thu Nov  2 11:35:12 1995
***************
*** 32,37 ****
--- 32,40 ----
   *	Libpvm message descriptors
   *
  $Log: pvmumbuf.c,v $
+  * Revision 1.9  1995/11/02  16:34:59  manchek
+  * umbuf_dump uses pvmnametag to get symbolic names
+  *
   * Revision 1.8  1995/07/18  17:02:22  manchek
   * added function umbuf_crc
   *
***************
*** 70,75 ****
--- 73,79 ----
  
  
  unsigned int pvmcrcappend();
+ char *pvmnametag();
  
  /***************
   **  Globals  **
***************
*** 85,91 ****
   **           **
   ***************/
  
! static char rcsid[] = "$Id: pvmumbuf.c,v 1.8 1995/07/18 17:02:22 manchek Exp $";
  static char pvmtxt[512];			/* scratch for error log */
  static int pvmmidhfree = 0;			/* head of midh free list */
  
--- 89,95 ----
   **           **
   ***************/
  
! static char rcsid[] = "$Id: pvmumbuf.c,v 1.9 1995/11/02 16:34:59 manchek Exp $";
  static char pvmtxt[512];			/* scratch for error log */
  static int pvmmidhfree = 0;			/* head of midh free list */
  
***************
*** 306,317 ****
  		setublen(up);
  #ifdef	MCHECKSUM
  	sprintf(pvmtxt,
! 	"umbuf_dump() mid=%d 0x%x src=t%x enc=%d cod=%d len=%d crc=0x%08x\n",
! 			mid, up, up->ub_src, up->ub_enc, up->ub_cod, up->ub_len,
! 			umbuf_crc(up));
  #else
! 	sprintf(pvmtxt, "umbuf_dump() mid=%d 0x%x src=t%x enc=%d cod=%d len=%d\n",
! 			mid, up, up->ub_src, up->ub_enc, up->ub_cod, up->ub_len);
  #endif
  	pvmlogerror(pvmtxt);
  	if (lvl > 0) {
--- 310,322 ----
  		setublen(up);
  #ifdef	MCHECKSUM
  	sprintf(pvmtxt,
! 	"umbuf_dump() mid=%d 0x%x src=t%x enc=%d cod=%s len=%d crc=0x%08x\n",
! 			mid, up, up->ub_src, up->ub_enc, pvmnametag(up->ub_cod, (int *)0),
! 			up->ub_len, umbuf_crc(up));
  #else
! 	sprintf(pvmtxt, "umbuf_dump() mid=%d 0x%x src=t%x enc=%d cod=%s len=%d\n",
! 			mid, up, up->ub_src, up->ub_enc, pvmnametag(up->ub_cod, (int *)0),
! 			up->ub_len);
  #endif
  	pvmlogerror(pvmtxt);
  	if (lvl > 0) {
*** ../netlib/pvm3.3.9/src/startup.c	Fri Jul 28 12:41:01 1995
--- src/startup.c	Thu Nov  2 11:36:23 1995
***************
*** 32,37 ****
--- 32,40 ----
   *	Exec more pvmds.  It's good for you.
   *
  $Log: startup.c,v $
+  * Revision 1.17  1995/11/02  16:36:14  manchek
+  * added NEEDSENDIAN switch
+  *
   * Revision 1.16  1995/07/28  16:41:01  manchek
   * wrap HASERRORVARS around errno declarations
   *
***************
*** 91,96 ****
--- 94,102 ----
  #ifdef NEEDENDIAN
  #include <endian.h>
  #endif
+ #ifdef NEEDSENDIAN
+ #include <sys/endian.h>
+ #endif
  #ifdef IMA_TITN
  #include <bsd/sys/types.h>
  #else
***************
*** 229,235 ****
   **           **
   ***************/
  
! static char rcsid[] = "$Id: startup.c,v 1.16 1995/07/28 16:41:01 manchek Exp $";
  static char pvmtxt[1024];		/* scratch for error log */
  
  
--- 235,241 ----
   **           **
   ***************/
  
! static char rcsid[] = "$Id: startup.c,v 1.17 1995/11/02 16:36:14 manchek Exp $";
  static char pvmtxt[1024];		/* scratch for error log */
  
  
*** ../netlib/pvm3.3.9/src/waitc.c	Fri Jul 28 12:04:07 1995
--- src/waitc.c	Thu Nov  2 11:36:46 1995
***************
*** 32,37 ****
--- 32,40 ----
   *	Wait context descriptors.
   *
  $Log: waitc.c,v $
+  * Revision 1.6  1995/11/02  16:36:44  manchek
+  * added NEEDSENDIAN switch
+  *
   * Revision 1.5  1995/07/28  16:04:07  manchek
   * switch endian includes on flag, not arch name
   *
***************
*** 57,62 ****
--- 60,68 ----
  #ifdef NEEDENDIAN
  #include <endian.h>
  #endif
+ #ifdef NEEDSENDIAN
+ #include <sys/endian.h>
+ #endif
  #ifdef IMA_TITN
  #include <bsd/sys/types.h>
  #else
***************
*** 102,108 ****
   **           **
   ***************/
  
! static char rcsid[] = "$Id: waitc.c,v 1.5 1995/07/28 16:04:07 manchek Exp $";
  static char pvmtxt[512];				/* scratch for error log */
  static char *waitnames[] = {
  	"addhost", "spawn", "hoststart", "task",
--- 108,114 ----
   **           **
   ***************/
  
! static char rcsid[] = "$Id: waitc.c,v 1.6 1995/11/02 16:36:44 manchek Exp $";
  static char pvmtxt[512];				/* scratch for error log */
  static char *waitnames[] = {
  	"addhost", "spawn", "hoststart", "task",
