*** Makefile.dist	Sat Jan 23 00:21:07 1993
--- Makefile	Sat Feb 13 15:19:15 1993
***************
*** 63,72 ****
  
  # If there are remote execution facilities defined,
  # enable them with switches here (see remote-*.c).
! REMOTE =
  
  # Any extra object files your system needs.
! extras =  getloadavg.o
  
  # Common prefix for machine-independent installed files.
  prefix = /usr/local
--- 63,78 ----
  
  # If there are remote execution facilities defined,
  # enable them with switches here (see remote-*.c).
! CUSTOMSSRC = /usr/local/src/icsi/pmake/customs
! REMOTE = -DCUSTOMS -I$(CUSTOMSSRC) \
!          -I$(CUSTOMSSRC)/../lib/include \
!          -I$(CUSTOMSSRC)/../lib/lst
  
  # Any extra object files your system needs.
! extras =  getloadavg.o \
! 	  $(CUSTOMSSRC)/customslib.o $(CUSTOMSSRC)/rpc.o $(CUSTOMSSRC)/xlog.o \
! 	  $(CUSTOMSSRC)/../lib/sprite/libsprite.a \
! 	  $(CUSTOMSSRC)/../lib/lst/liblst.a
  
  # Common prefix for machine-independent installed files.
  prefix = /usr/local
***************
*** 91,96 ****
--- 97,104 ----
  # On many systems, the getloadavg function (used to implement the `-l'
  # switch) will not work unless make is installed setgid kmem.
  install_setgid = true
+ # Install make setuid for use with customs
+ user = root
  # Install make setgid to this group so it can read /dev/kmem.
  group = kmem
  
***************
*** 153,159 ****
  .c.o:
  	$(CC) $(defines) -c -I. -I$(srcdir) -I$(srcdir)/glob \
  	      $(CFLAGS) $< $(OUTPUT_OPTION)
! remote.o: remote.c
  	$(CC) $(defines) $(REMOTE) -c -I. -I$(srcdir) \
  	      $(CFLAGS) $(srcdir)/remote.c
  
--- 161,167 ----
  .c.o:
  	$(CC) $(defines) -c -I. -I$(srcdir) -I$(srcdir)/glob \
  	      $(CFLAGS) $< $(OUTPUT_OPTION)
! remote.o: remote.c remote-stub.c remote-cstms.c
  	$(CC) $(defines) $(REMOTE) -c -I. -I$(srcdir) \
  	      $(CFLAGS) $(srcdir)/remote.c
  
***************
*** 179,185 ****
  	$(INSTALL_PROGRAM) make $@.new
  # These are necessary for load-average checking to work on most Unix machines.
  	if $(install_setgid); then \
! 	  chgrp $(group) $@.new && chmod g+s $@.new; \
  	else true; fi
  	mv $@.new $@
  
--- 187,200 ----
  	$(INSTALL_PROGRAM) make $@.new
  # These are necessary for load-average checking to work on most Unix machines.
  	if $(install_setgid); then \
! 		if [ "$(group)" ]; then \
! 			chgrp $(group) $@.new ; \
! 			chmod g+s $@.new ; \
! 		fi
! 		if [ "$(user)" ]; then \
! 			chown $(user) $@.new ; \
! 			chmod u+s $@.new ; \
! 		fi \
  	else true; fi
  	mv $@.new $@
  
*** job.c.dist	Fri Jan 22 14:31:27 1993
--- job.c	Fri Jan 22 23:57:30 1993
***************
*** 415,421 ****
  #ifdef	POSIX
  extern sigset_t fatal_signal_set;
  
! static void
  unblock_sigs ()
  {
    sigset_t empty;
--- 415,421 ----
  #ifdef	POSIX
  extern sigset_t fatal_signal_set;
  
! void
  unblock_sigs ()
  {
    sigset_t empty;
***************
*** 422,434 ****
    sigemptyset (&empty);
    sigprocmask (SIG_SETMASK, &empty, (sigset_t *) 0);
  }
- #else
- #ifdef	HAVE_SIGSETMASK
- extern int fatal_signal_mask;
- #define	unblock_sigs()	sigsetmask (0)
- #else
- #define	unblock_sigs()
- #endif
  #endif
  
  /* Start a job to run the commands specified in CHILD.
--- 422,427 ----
*** job.h.dist	Wed Jan  6 14:57:14 1993
--- job.h	Fri Jan 22 23:57:17 1993
***************
*** 44,49 ****
--- 44,60 ----
  extern void reap_children ();
  extern void start_waiting_jobs ();
  
+ #ifdef	POSIX
+ extern void unblock_sigs ();
+ #else
+ #ifdef	HAVE_SIGSETMASK
+ extern int fatal_signal_mask;
+ #define	unblock_sigs()	sigsetmask (0)
+ #else
+ #define	unblock_sigs()
+ #endif
+ #endif
+ 
  extern char **construct_command_argv ();
  extern void child_execute_job ();
  extern void exec_command ();
*** make.h.dist	Fri Jan 15 10:05:49 1993
--- make.h	Sat Jan 23 00:03:31 1993
***************
*** 165,172 ****
  
  #endif	/* USG.  */
  
! extern char *malloc (), *realloc ();
  extern void free ();
  
  extern void qsort ();
  extern void abort (), exit ();
--- 165,177 ----
  
  #endif	/* USG.  */
  
! #ifdef __STDC__
! extern void *malloc (), *realloc ();
  extern void free ();
+ #else
+ extern char *malloc (), *realloc ();
+ extern int free ();
+ #endif
  
  extern void qsort ();
  extern void abort (), exit ();
*** remote-cstms.c.dist	Sat Jul  4 17:52:45 1992
--- remote-cstms.c	Sat Jan 23 00:08:10 1993
***************
*** 23,46 ****
  
  #include "make.h"
  #include "commands.h"
  #include "customs.h"
  #include <sys/time.h>
  
  
  char *remote_description = "Customs";
  
  
  /* ExportPermit gotten by start_remote_job_p, and used by start_remote_job.  */
  static ExportPermit permit;
  
  /* Return nonzero if the next job should be done remotely.  */
  
  int
  start_remote_job_p ()
  {
!   if (Customs_Host (EXPORT_SAME, &permit) != RPC_SUCCESS)
!     return 0;
  
    return !CUSTOMS_FAIL (&permit.addr);
  }
  
--- 23,92 ----
  
  #include "make.h"
  #include "commands.h"
+ #include "job.h"
  #include "customs.h"
  #include <sys/time.h>
+ #include <netdb.h>
  
  
  char *remote_description = "Customs";
  
+ /* Program to monitor remote job.  Use absolute path to cut some overhead. */
+ #define EXPORT	"/usr/local/bin/export"
  
  /* ExportPermit gotten by start_remote_job_p, and used by start_remote_job.  */
  static ExportPermit permit;
  
+ static int remoteInit = 0;
+ static int noExport = 0;
+ 
+ /* Initialize remote excecution system. */
+ static void
+ remote_init ()
+ {
+   /* We may need to be root to make customs believe our uid.  In that case
+    * gnumake should be installed suid root.  */
+   make_access ();
+ 
+   /*
+    * Check for customs daemon.  Implicitly initializes customslib and creates
+    * socket to local daemon.
+    */
+   if (Customs_Ping() != RPC_SUCCESS)
+       noExport = 1;
+ 
+   remoteInit = 1;
+   user_access ();
+ 
+   return;
+ }
+ 
  /* Return nonzero if the next job should be done remotely.  */
  
  int
  start_remote_job_p ()
  {
!   Rpc_Stat status;
  
+   if (!remoteInit)
+       remote_init ();
+ 
+   if (noExport)
+       return 0;
+ 
+   /* the first job should run locally, or, if the -l flag is given, we use
+      that as clue as to how many local jobs should be scheduled locally */
+   if (max_load_average < 0 && job_slots_used == 0
+       || job_slots_used < max_load_average)
+      return 0;
+ 
+   status = Customs_Host (EXPORT_SAME, &permit);
+   if (status != RPC_SUCCESS)
+     {
+       error ("exporting: %s", Rpc_ErrorMessage (status));
+       return 0;
+     }
+ 
    return !CUSTOMS_FAIL (&permit.addr);
  }
  
***************
*** 62,67 ****
--- 108,114 ----
    extern int vfork (), execve ();
    PATH_VAR (cwd);
    char waybill[MAX_DATA_SIZE], msg[128];
+   WayBill *wb;
    struct timeval timeout;
    struct sockaddr_in sin;
    int len;
***************
*** 80,85 ****
--- 127,138 ----
        return 1;
      }
  
+   if (Customs_NormPath(cwd, GET_PATH_MAX) < 0)
+     {
+       error ("exporting: path normalization failed: %s", cwd);
+       return 1;
+     }
+ 
    /* Create the return socket.  */
    retsock = Rpc_UdpCreate (True, 0);
    if (retsock < 0)
***************
*** 105,110 ****
--- 158,169 ----
    len = Customs_MakeWayBill (&permit, cwd, argv[0], argv,
  			     envp, retport, waybill);
  
+   /* Fix up the read uid and gid in the waybill to compensate for our own
+      suid/sgid status.  */
+   wb = (WayBill *)waybill;
+   wb->ruid = wb->euid;
+   wb->rgid = wb->egid;
+ 
    /* Send the request to the server, timing out in 20 seconds.  */
    timeout.tv_usec = 0;
    timeout.tv_sec = 20;
***************
*** 129,135 ****
--- 188,211 ----
        error ("CUSTOMS_IMPORT: %s", msg);
        return 1;
      }
+   else
+     {
+       struct hostent *he;
  
+       he = gethostbyaddr(&permit.addr,
+ 			 sizeof(permit.addr),
+ 			 AF_INET);
+       if (he == (struct hostent *)NULL) {
+ 	  error("*** exported to %s (id %u)",
+ 		InetNtoA(permit.addr),
+ 		permit.id);
+       } else {
+ 	  error("*** exported to %s (id %u)",
+ 		he->h_name,
+ 		permit.id);
+       }
+     }
+ 
    fflush (stdout);
    fflush (stderr);
  
***************
*** 145,156 ****
        /* Child side.  Run `export' to handle the connection.  */
        static char sock_buf[20], retsock_buf[20], id_buf[20];
        static char *new_argv[6] =
! 	{ "export", "-id", sock_buf, retsock_buf, id_buf, 0 };
  
        /* Set up the arguments.  */
        (void) sprintf (sock_buf, "%d", sock);
        (void) sprintf (retsock_buf, "%d", retsock);
        (void) sprintf (id_buf, "%x", permit.id);
  
        /* Run the command.  */
        (void) execvp (new_argv[0], new_argv);
--- 221,238 ----
        /* Child side.  Run `export' to handle the connection.  */
        static char sock_buf[20], retsock_buf[20], id_buf[20];
        static char *new_argv[6] =
! 	{ EXPORT, "-id", sock_buf, retsock_buf, id_buf, 0 };
  
        /* Set up the arguments.  */
        (void) sprintf (sock_buf, "%d", sock);
        (void) sprintf (retsock_buf, "%d", retsock);
        (void) sprintf (id_buf, "%x", permit.id);
+ 
+       /* Don't block signals for the new process.  */
+       unblock_sigs ();
+ 
+       /* Be the user, permanently.  */
+       child_access ();
  
        /* Run the command.  */
        (void) execvp (new_argv[0], new_argv);
