[comp.protocols.appletalk] Executing remote Unix processes from a Mac

paul@lfcs.ed.ac.uk (Paul Anderson) (09/28/89)

Here are the patches to Aufs that allow a Mac to execute proceses on the
Unix Host.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 2)."
# Contents:  MANIFEST README.PROCESS afproc.c afproc.h hypertalk
# Wrapped by paul@uist on Mon Sep 25 09:38:33 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f MANIFEST -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"MANIFEST\"
else
echo shar: Extracting \"MANIFEST\" \(294 characters\)
sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X MANIFEST                  1	This shipping list
X README.PROCESS            1	
X afproc.c                  1	
X afproc.h                  1	
X aufs.diffs                2	
X hypertalk                 1	
END_OF_MANIFEST
if test 294 -ne `wc -c <MANIFEST`; then
    echo shar: \"MANIFEST\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README.PROCESS -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README.PROCESS\"
else
echo shar: Extracting \"README.PROCESS\" \(4578 characters\)
sed "s/^X//" >README.PROCESS <<'END_OF_README.PROCESS'
X
XExecuting Unix Processes from a Macintosh
X=========================================
X
XThis package contains some extensions to the AUFS file server enabling
XMacintosh programs to execute and communicate with processes on the Unix host.
X
XInstallation
X============
X
XThis distribution contains a number of additional source files and a set
Xof patches to the version of AUFS distributed with CAP 5.0. To build the
Xnew server, take a copy of the CAP 5.0 AUFS source directory and apply
Xthe patches -
X
X	patch <aufs.diffs
X
XThe patches to the Makefile may need examining if your options are different
Xfrom the ones used here.
X
XThe Code has been tested on Sun3 and Sun4, under SunOS 4.0.
XIf you have a different Unix, then some work might be needed on the
Xprocess handling code in the file afproc.c.
XI would like to hear of any problems and/or fixes for other machines.
X
XThis should now compile to make a new version of the AUFS server.
X
XStarting the server
X===================
X
XThe server has an additional option -p to enable the remote process function.
XIf the -p option is not given, the server will reject all process requests.
X
XThere is also an extra debugging option "Process", so the server can
Xbe started with the debugging option "-a Process" to trace the process
Xfunctions being executed.
X
XUsing the server
X================
X
XThe server behaves in exactly same way as the normal AUFS server, except
Xwhen an attempt is made to open a file with a name preceeded by "|".
XIn this case, the remainder of the name is expected to be a file containing
XUnix binary code which the server attempts to execute in a separate fork.
XThe output from the command can be found by reading the file and input
Xcan be supplied to the command by writing to the file.
X
XThe file can be closed and re-opened without the process being killed -
Xto interrupt or kill the process, write CTRL-C or CTRL-\ to the file.
XWriting CTRL-D sets EOF on the process input.
XThe process is also killed when the volume is unmounted.
X
XReading from the process does not block - if the process has no output pending
Xafter 1 second, then the read call returns.
XAll sucessful data reads are terminated with a CTRL-D control code -
X
XRead returns just a CTRL-D	- The process had no output ready after
X				  the 1 second timeout period.
X
XRead return data + CTRL-D	- The process had data ready.
X	                          More data may be available.
X
XRead returns no bytes		- EOF condition. the process has died.
X
XAll the above control characters, as well as the read timeout period can
Xbe changed by writing escape sequences to the process -
X
X	<ESC> INT = nn <CR>	- set interrupt char to nn (decimal)
X	<ESC> KIL = nn <CR>	- set kill char to nn (decimal)
X	<ESC> EOF = nn <CR>	- set EOF char to nn (decimal)
X	<ESC> IDL = nn <CR>	- set end of data char to nn (decimal)
X	<ESC> ON = nn <CR>	- set escape char to nn (decimal)
X	<ESC> OFF = nn <CR>	- set end of escape seq char to nn (decimal)
X	<ESC> TIM = nn <CR>	- set read timeout to nn seconds
X
XThe control codes can be set to -1 to disable them totally.
X
XExample
X=======
X
XTo interact with a Unix process such as a shell or an interpreter, the
XMacintosh program will normally issue a command then read a reply.
XTo maintain synchronization, there needs to be some way for the
XMacintosh to identify the end of the reply and it is easiest if the
XUnix process supplies a unique prompt as a "turnaround" character.
X
XThe code then typically looks something like ...
X
X	open( "|code-file-name" )
X
X	repeat
X
X		write( "command" )
X
X		while true
X
X			read( data, len )		Read the data
X			if (len==0) break		Must be EOF
X			if (len==1) continue		Timeout
X			Display( data, len-1 )		Show the returned data
X			if (data[len-2]=prompt) break	End of reply
X		end
X
X	until done
X
X	write( EOF )
X
X	close()
X
XThis code keeps polling the remote process for data. If the remote
Xprocess is expected to take some time, the read timeout period can be changed
X(using the control codes) to decrease the polling frequency, but the
XMac cannot be interrupted by the user whilst inside the read call, so
Xthis increases the response time to any keyboard break-in.
X
XThe file Hypertalk shows an example of Hypertalk code which uses a CTRL-G
Xcharacter as the turnaround. These could be used to issue commands to a
Xshell which rings the bell as a prompt.
X
X
X
XPaul Anderson                      JANET: paul@uk.ac.ed.lfcs
XLFCS, Dept. of Computer Science    UUCP:  ..!mcvax!ukc!lfcs!paul	
XUniversity of Edinburgh            ARPA:  paul%lfcs.ed.ac.uk@nsfnet-relay.ac.uk
XEdinburgh EH9 3JZ, UK.             Tel:   031-667-1081 Ext 2788
END_OF_README.PROCESS
if test 4578 -ne `wc -c <README.PROCESS`; then
    echo shar: \"README.PROCESS\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f afproc.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"afproc.c\"
else
echo shar: Extracting \"afproc.c\" \(11943 characters\)
sed "s/^X//" >afproc.c <<'END_OF_afproc.c'
X/*
X * $Author: paul $
X * $Header: /tmp_mnt/auto1b00053/paul/code/aufs/p2/RCS/afproc.c,v 1.6 89/06/28 17:20:36 paul Exp $
X * $Revision: 1.6 $
X*/
X
X/* Extended routines for AUFS to allow communication with UNIX processes.
X*/
X
Xstatic char rcsid[]="$Header: /tmp_mnt/auto1b00053/paul/code/aufs/p2/RCS/afproc.c,v 1.6 89/06/28 17:20:36 paul Exp $"; /* RCS identifier */
X
X#include <stdio.h>
X#include <sys/filio.h>
X#include <sys/file.h>
X#include <sys/signal.h>
X#include <netat/appletalk.h>
X#include <netat/afp.h>
X#include <errno.h>
X#include <netat/afpcmd.h>
X#include <signal.h>
X#include "afps.h"
X#include "afpvols.h"
X#include "afppasswd.h"
X#include "afposncs.h"
X#include "afpgc.h"
X#include "afproc.h"
X
Xexport void ProcInit();
Xexport void ProcCleanup();
Xexport PROCESS *FindProcess();
Xexport OSErr ProcOpen();
Xexport OSErr ProcClose();
Xexport OSErr ProcRead();
Xexport OSErr ProcWrite();
Xexport OSErr ProcDelete();
X
Ximport int errno;
Ximport int enableProcs;
X
XPROCESS *procList = NULL;	/* Linked list of process records */
X
Xexport PROCESS
X*FindProcess( fd )
Xint fd;
X{
X  PROCESS *p = procList;
X
X  /* Find any attached process corresponding to this FD */
X  while (p) {
X    if ( (p->status&OPEN) && (p->fdo[0]==fd) ) return p;
X    p = p->nextProc;
X  }
X  return NULL;
X}
X
Xprivate void
XCheckProcess( p )
XPROCESS *p;
X{
X  /* See if the process has died */
X  /* If it stops (Uh?) hit it on the head */
X  if ((p->status&RUNP)==0) return;
X  else for (;;) {
X    if ( wait4( p->pid, &(p->termStat), WNOHANG, NULL ) != 0 ) {
X      if (p->termStat.w_stopval==WSTOPPED) {
X	if (DBPRO)
X	  printf( "PROCESS: Stopped: [%08x] %s status=%04x\n", 
X		 (unsigned)p, p->cmnd, p->status );
X	kill( p->pid, SIGKILL );
X      } else {
X	if (DBPRO)
X	  if (p->termStat.w_termsig == 0)
X	    printf( "PROCESS: Died: [%08x] %s exit=%04x\n", 
X		   (unsigned)p, p->cmnd, p->termStat.w_retcode );
X	  else
X	    printf( "PROCESS: Died: [%08x] %s signal=%04x\n", 
X		   (unsigned)p, p->cmnd, p->termStat.w_termsig );
X	p->status &= ~RUNP;
X	return;
X      }
X    } else return;
X  }
X}
X
Xprivate void
XKillProcess( p )
XPROCESS *p;
X{
X  int timer;
X
X  /* Give it two sec<onds to terminate by itself */
X  for (timer=0; timer<EXIT_GRACE; ++timer) {
X    if ( wait4( p->pid, &(p->termStat), WNOHANG, NULL ) > 0 ) break;
X    abSleep( sectotick(1), TRUE );
X  }
X
X  /* Give it a hangup, then another two seconds to clean up */
X  if ( wait4( p->pid, &(p->termStat), WNOHANG, NULL ) == 0 ) {
X    if (DBPRO)
X      printf( "PROCESS: Hanging Up: [%08x] %s\n", (unsigned)p, p->cmnd );
X    kill( p->pid, SIGHUP );
X    for (timer=0; timer<HUP_GRACE; ++timer) {
X      if ( wait4( p->pid, &(p->termStat), WNOHANG, NULL ) > 0 ) break;
X      abSleep( sectotick(1), TRUE );
X    }
X  }
X
X  /* If it still hasnt gone, kill it */
X  if ( wait4( p->pid, &(p->termStat), WNOHANG, NULL ) == 0 ) {
X    if (DBPRO)
X      printf( "PROCESS: Killing: [%08x] %s\n", (unsigned)p, p->cmnd );
X    kill( p->pid, SIGKILL );
X  }
X
X  /* Now wait for it */
X  while ( wait4( p->pid, &(p->termStat), WNOHANG, NULL ) == 0 )
X    abSleep( 2, TRUE );;
X  if (DBPRO)
X    if (p->termStat.w_termsig == 0)
X      printf( "PROCESS: Died: [%08x] %s exit=%04x\n", 
X	     (unsigned)p, p->cmnd, p->termStat.w_retcode );
X    else
X      printf( "PROCESS: Died: [%08x] %s signal=%04x\n", 
X	     (unsigned)p, p->cmnd, p->termStat.w_termsig );
X
X  /* Mark it as not running */
X  p->status &= ~RUNP;
X}
X
Xprivate void
XDeleteProcess( p )
XPROCESS *p;
X{
X  PROCESS *q = p->nextProc;
X  PROCESS *s = procList;
X
X  /* Kill the process if its running */
X  if (p->status&RUNP) KillProcess(p);
X
X  /* Close all pipes */
X  if (p->status&FDI0) close(p->fdi[0]);
X  if (p->status&FDI1) close(p->fdi[1]);
X  if (p->status&FDO0) close(p->fdo[0]);
X  if (p->status&FDO1) close(p->fdo[1]);
X
X  /* Delete the process record */
X  free(p->cmnd); free(p);
X  if (p=procList) {
X    procList = q;
X  } else {
X    while (s->nextProc != p) s = s->nextProc;
X    s->nextProc = q;
X  }
X}
X
Xexport void
XProcCleanup()
X{
X  log( "Process cleanup" );
X
X  while (procList) {
X    log( "Terminating %s pid=%d", procList->cmnd, procList->pid );
X    DeleteProcess(procList);
X  }
X}
X
Xexport void
XProcInit()
X{
X  if (enableProcs)
X    log( "Process code $Revision: 1.6 $ ** Enabled" );
X  else
X    log( "Process code $Revision: 1.6 $ ** Disabled" );
X}
X
Xexport OSErr
XProcDelete( path )
Xchar *path;
X{
X  PROCESS *p = procList;
X
X  if (DBPRO)
X    printf( "PROCESS: Deleting: %s\n", path );
X
X  while (p) {
X    if ( ((p->status&OPEN)==0) && (strcmp(path,p->cmnd)==0) ) {
X      DeleteProcess(p);
X      return(noErr);
X    }
X    p = p->nextProc;
X  }
X  return(peNoProcess);
X}
X
Xexport OSErr
XProcOpen( path, mo, fhdl )
Xchar *path;
Xint mo;
Xint *fhdl;
X{
X  PROCESS *p = procList;
X  PROCESS *q;
X  int block = 1;
X
X  if (!enableProcs) return(peDisabled);
X
X  /* Re-attach to any matching detached processes */
X  while (p) {
X    q = p->nextProc;
X    if ( ((p->status&OPEN)==0) && (strcmp(path,p->cmnd)==0) ) {
X      CheckProcess( p );
X      if ((p->status&RUNP)==0) {
X	DeleteProcess( p );
X      } else {
X	if (DBPRO)
X	  printf( "PROCESS: Attaching: [%08x] %s\n", (unsigned)p, path );
X	p->status |= OPEN;
X	*fhdl = p->fdo[0];
X	return(noErr);
X      }
X    }
X    p = q;
X  }
X
X  /* Otherwise open a new process record */
X  if (DBPRO)
X    printf( "PROCESS: Opening: %s\n", path );
X
X  if ( access( path, X_OK ) == -1 ) return(peNoExec);
X
X  if ( !( p=(PROCESS*)malloc( sizeof(*p) ) ) ) return(peSysErr);
X
X  if ( !( p->cmnd=malloc( 1+strlen(path) ) ) ) {
X    free(p); return(peSysErr);
X  }
X
X  /* Initialize the process record with the defaults */
X  strcpy( p->cmnd, path );
X  bzero( &(p->codes[0]), 256 );
X  p->codes[DEF_EOF] = EOF_SIG;
X  p->codes[DEF_INT] = INT_SIG;
X  p->codes[DEF_KIL] = KIL_SIG;
X  p->codes[DEF_ON]  = ESC_ON;
X  p->codes[DEF_OFF] = ESC_OFF;
X  p->recSep = DEF_RS;
X  p->timeOut = DEF_TIMEOUT;
X  p->inEsc = FALSE;
X  p->escCount = 0;
X  p->status = OPEN;
X
X  /* Open the pipes */
X  if ( ( pipe(&p->fdi[0]) == -1 ) || ( pipe(&p->fdo[0]) == -1 ) ) {
X    free(p->cmnd); free(p); return(peSysErr);
X  }
X  p->status |= (FDI0|FDI1|FDO0|FDO1);
X
X  ioctl( p->fdi[1], FIONBIO, &block );
X
X  p->nextProc = procList;
X  procList = p;
X  *fhdl = p->fdo[0];
X
X  if (DBPRO)
X    printf( "PROCESS: Starting: [%08x] %s\n", (unsigned)p, p->cmnd );
X
X  if (p->pid=fork()) {
X    close(p->fdi[0]);
X    close(p->fdo[1]);
X    p->status &= ~(FDI0|FDO1);
X    p->status |= RUNP;
X  } else {
X    dup2(p->fdi[0],0);
X    dup2(p->fdo[1],1);
X    dup2(p->fdo[1],2);
X    close(p->fdi[0]);
X    close(p->fdi[1]);
X    close(p->fdo[0]);
X    close(p->fdo[1]);
X    execlp( p->cmnd, p->cmnd, (char*)0 );
X    exit(procFail);
X  }
X
X  return(noErr);
X}
X
Xexport OSErr
XProcClose( p )
XPROCESS *p;
X{
X  if (DBPRO)
X    printf( "PROCESS: Closing: [%08x]\n", (unsigned)p );
X
X  CheckProcess( p );
X  if ((p->status&RUNP)==0) DeleteProcess(p);
X  else p->status &= ~OPEN;
X
X  return(noErr);
X}
X
Xprivate OSErr
XWriteData( p, buf, len )
XPROCESS *p;
Xchar *buf;
Xint len;
X{
X  int i, count;
X
X  if (len<=0) return(noErr);
X
X  if (p->inEsc) {
X    if (len+p->escCount > ESC_SIZE) return(peESCErr);
X    bcopy( buf, &(p->escBufr[p->escCount]), len );
X    p->escCount += len;
X    return(noErr);
X  }
X
X  if (DBPRO)
X    printf( "PROCESS: Writing: [%08x] %s bytes=%d\n",
X	   (unsigned)p, p->cmnd, len );
X
X  /* Make sure that the process is available */
X  CheckProcess( p );
X  if ((p->status&OPEN)==0) return(peImpossible);
X  if ((p->status&RUNP)==0) return(peDeadProc);
X  if ((p->status&FDI1)==0) return(peShutProc);
X
X  /* Translate the new lines */
X  for (i=0; i<len; ++i) if (buf[i]==ENEWLINE) buf[i]=INEWLINE;
X
X  /* Write the data */
X  for (;;) {
X    count = write( p->fdi[1], buf, len );
X    if (count==len) break;
X    else if (count>0) { len-=count; buf=&buf[count]; }
X    else {
X      if (errno==EWOULDBLOCK) return(peBlock);
X      else {
X	CheckProcess( p );
X	return(peSysErr);
X      }
X    }
X  }
X  return (noErr);
X}
X
Xprivate OSErr
XSetCode( p, code, value )
XPROCESS *p;
Xint code, value;
X{
X  int i;
X
X  if ((value<-1)||(value>255)) return(peESCErr);
X  for (i=0;i<256;++i) {
X    if (p->codes[i]==code) {
X      p->codes[i]=NORMAL;
X      break;
X    }
X  }
X  if (value>=0) p->codes[value]=code;
X  return(noErr);
X}
X
Xprivate OSErr
XProcControl( p )
XPROCESS *p;
X{
X  char cmnd[ESC_SIZE+1];
X  int value, count;
X  char *s;
X
X  if (DBPRO) {
X    printf( "PROCESS: Control: [%08x] ", (unsigned)p );
X    for ( s=p->escBufr; s < &(p->escBufr[p->escCount]); ++s ) putchar(*s);
X    putchar( '\n' );
X  }
X  
X  count = sscanf( p->escBufr, " %[^= ] = %d %c", cmnd, &value, &count );
X  if (count != 2) return(peESCErr);
X
X  if      (strcmp(cmnd,"EOF")==0) return SetCode( p, EOF_SIG, value );
X  else if (strcmp(cmnd,"INT")==0) return SetCode( p, INT_SIG, value );
X  else if (strcmp(cmnd,"KIL")==0) return SetCode( p, KIL_SIG, value );
X  else if (strcmp(cmnd,"ON" )==0) return SetCode( p, ESC_ON, value );
X  else if (strcmp(cmnd,"OFF")==0) return SetCode( p, ESC_OFF, value );
X  else if (strcmp(cmnd,"TIM")==0) {
X    if ((value<0)||(value>60)) return(peESCErr);
X    else p->timeOut=value;
X  } else if (strcmp(cmnd,"IDL")==0) {
X    if ((value<0)||(value>255)) return(peESCErr);
X    else p->recSep=value;
X  }
X  else return(peESCErr);
X}
X
Xexport OSErr
XProcSignal( p, sig )
XPROCESS *p;
Xint sig;
X{
X  if (DBPRO)
X    printf( "PROCESS: Signalling: [%08x] %s signal=%d\n",
X	   (unsigned)p, p->cmnd, sig );
X
X  switch (sig) {
X  case INT_SIG:
X    if (kill( p->pid, SIGINT ) == -1) {
X      CheckProcess( p );
X      if ((p->status&RUNP)==0) return(peDeadProc);
X      else return(peSysErr);
X    }
X    break;	 
X  case KIL_SIG:
X    if (kill( p->pid, SIGKILL ) == -1) {
X      CheckProcess( p );
X      if ((p->status&RUNP)==0) return(peDeadProc);
X      else return(peSysErr);
X    }
X    break;
X  case EOF_SIG:
X    if (p->status&FDI1) {
X      close( p->fdi[1] );
X      p->status &= ~FDI1;
X    }
X    break;
X  case ESC_ON:
X    p->inEsc = TRUE;
X    p->escCount = 0;
X    break;
X  case ESC_OFF:
X    p->inEsc = FALSE;
X    p->escBufr[p->escCount] = '\0';
X    return ProcControl( p );
X  default:
X    break;
X  }
X  return (noErr);
X}
X
Xexport OSErr
XProcWrite( p, buf, len )
XPROCESS *p;
Xchar *buf;
Xint len;
X{
X  register char *s=buf, *t;
X  int result, c;
X
X  for ( t=s; t<&buf[len]; ++t ) {
X    c = p->codes[*t];
X    if ((!p->inEsc && (c!=NORMAL) && (c!=ESC_OFF)) ||
X	( p->inEsc && (c==ESC_OFF)) ) {
X      if (t>s) {
X	result = WriteData( p, s, (int)(t-s) );
X	if (result != noErr) return(result);
X      }
X      result = ProcSignal( p, c );
X      if (result != noErr) return(result);
X      s = t+1;
X    }
X  }
X  if (t>s) return WriteData( p, s, (int)(t-s) );
X  else return(noErr);
X}
X
Xexport OSErr
XProcRead( p, buf, len, rl )
XPROCESS *p;
Xchar *buf;
Xint len;
Xint *rl;
X{
X  long count;
X  int ticks;
X
X  if (DBPRO)
X    printf( "PROCESS: Reading: [%08x] %s\n", (unsigned)p, p->cmnd );
X
X  for ( count=0, ticks=2*(p->timeOut); count==0; --ticks ) {
X
X    /* Make sure that the process is available */
X    CheckProcess( p );
X    if ((p->status&FDO0)==0) return(peImpossible);
X    if ((p->status&OPEN)==0) return(peImpossible);
X
X    /* See if there is any data to read */
X    if ( ioctl( p->fdo[0], FIONREAD, &count ) == - 1 ) {
X      CheckProcess( p );
X      if ((p->status&RUNP)==0) return(peEOFErr);
X      else return(peSysErr);
X    }
X
X    /* Otherwise, check for timeout & return and record separator */
X    if (count<=0) {
X      if ((p->status&RUNP)==0) return(peEOFErr);
X      if (ticks<=0) {
X	if (DBPRO)
X	  printf( "PROCESS: Timeout: [%08x] %s\n", (unsigned)p, p->cmnd );
X	*buf = p->recSep;
X	*rl = 1;
X	return (noErr);
X      } else {
X	abSleep( (sectotick(1)/2), TRUE );
X      }
X    }
X  }
X
X  /* Otherwise, read the data */
X  count = read( p->fdo[0], buf, (count>len-1)?len-1:(int)count );
X  if (count<0) {
X    CheckProcess( p );
X    return(peSysErr);
X  }
X  buf[count++] = p->recSep;
X
X  /* Translate the new lines */
X  while (*buf) { if (*buf==INEWLINE) *buf=ENEWLINE; ++buf; }
X
X  if (DBPRO)
X    printf( "PROCESS: Read: [%08x] %s bytes=%d\n",
X	   (unsigned)p, p->cmnd, count );
X
X  *rl = count;
X  return (noErr);
X}
END_OF_afproc.c
if test 11943 -ne `wc -c <afproc.c`; then
    echo shar: \"afproc.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f afproc.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"afproc.h\"
else
echo shar: Extracting \"afproc.h\" \(3358 characters\)
sed "s/^X//" >afproc.h <<'END_OF_afproc.h'
X#include <sys/wait.h>
X
X/* Process name syntax */
X
X#define IsProcess(fn) (*fn=='|')
X#define NameOf(fn) (IsProcess(fn)?&fn[1]:fn)
X
X/* Process error codes */
X
X#define peInvalid aeObjectTypeErr      /* Operation not allowed on process */
X#define peNoProcess aeObjectNotFound   /* No process with this name */
X#define peNoExec aeObjectTypeErr       /* Can't execute process file */
X#define peSysErr aeMiscErr             /* System error (malloc etc) */
X#define peImpossible aeMiscErr         /* Repeated process close etc. */
X#define peShutProc aeSessClosed        /* Writing to process after EOF_SIG */
X#define peDeadProc aeSessClosed        /* Writing to dead process */
X#define peBlock aeFileBusy             /* Write would block */
X#define peEOFErr aeEOFErr              /* EOF or dead on read */
X#define peDisabled aeCallNotSupported  /* Process code not enabled */
X#define peESCErr aeParamErr            /* Illegal ESC sequence */
X
X/* Active process record */
X
X#define ESC_SIZE 32             /* Max size od ESC sequence */
X
Xtypedef struct process {
X  int pid;			/* Process ID */
X  union wait termStat;		/* Termination status */
X  int fdi[2];			/* Input pipe to process */
X  int fdo[2];			/* Output pipe from process */
X  int status;                   /* Process status (see below) */
X  char codes[256];              /* Special characters (see below) */
X  int timeOut;                  /* No. of secs to wait for data on read */
X  int escCount;                 /* No. of bytes in ESC buffer */
X  int inEsc;                    /* TRUE when reading ESC sequence */
X  char *cmnd;			/* Process command line */
X  struct process *nextProc;	/* Pointer to next process record */
X  char escBufr[ESC_SIZE+1];     /* Buffer for ESC sequences */
X  char recSep;                  /* Record separator character */
X} PROCESS;
X
X/* States in process record */
X
X#define FDI0 0x01               /* We have fdi[0] open */
X#define FDI1 0x02               /* We have fdi[1] open */
X#define FDO0 0x04               /* We have fdo[0] open */
X#define FDO1 0x08               /* We have fdo[1] open */
X#define RUNP 0x10               /* Process has been forked, but not reaped */
X#define OPEN 0x20               /* Mac has fd open on process */
X
X/* Special character interpretations  */
X
X#define NORMAL  0               /* Normal character to be written to process */
X#define EOF_SIG 1               /* Close input pipe to process */
X#define INT_SIG 2               /* Send SIGINT to process */
X#define KIL_SIG 3               /* Send SIGKILL to process */
X#define ESC_ON  4               /* Start of ESC sequence */
X#define ESC_OFF 5               /* End of ESC sequence */
X
X/* Default values */
X
X#define DEF_EOF 0x04            /* Default character for EOF_SIG */
X#define DEF_INT 0x03            /* Default character for INT_SIG */
X#define DEF_KIL 0x1c            /* Default character for KIL_SIG */
X#define DEF_RS  0x04            /* Default character for recSep */
X#define DEF_ON  0x1b            /* Default character for ESC_ON */
X#define DEF_OFF 0x0d            /* Default character for ESC_OFF */
X
X#define DEF_TIMEOUT 1           /* Default read timeout */
X#define EXIT_GRACE 2            /* Clean up time allowed before HUP */
X#define HUP_GRACE 2             /* Clean up time allowed before KILL */
X
X/* termStat values */
X
X#define procFail 0x99           /* Failed exec */
X
X
X
END_OF_afproc.h
if test 3358 -ne `wc -c <afproc.h`; then
    echo shar: \"afproc.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f hypertalk -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"hypertalk\"
else
echo shar: Extracting \"hypertalk\" \(1554 characters\)
sed "s/^X//" >hypertalk <<'END_OF_hypertalk'
X-- These Hypertalk routines show how to communicate with a remote
X-- Process which return CTRL-G as a prompt when it has finished processing
X-- a command.
X
X-- The startup process uses an XCMD "mount" to mount the aufs server
X-- volume automatically.
X
Xfunction startProcess theProcess
X  global currentProcess
X  global thePrompt
X  put the numToChar of 7 into thePrompt
X  ask "Enter password:"
X  put it into password
X  mount "", "YOUR-SERVER-NAME", "YOUR-VOLUME-NAME", "YOUR-USER-NAME", password
X  if the result is not empty then beep
X  put "Processes" & ":|" & theProcess into currentProcess
X  open file currentProcess
Xend startProcess
X
Xfunction endProcess
X  global currentProcess
X  write numToChar of 4 to file currentProcess
X  close file currentProcess
X  unmount "Processes"
Xend endProcess
X
Xfunction sendCommand theCommand
X  global currentProcess
X  write theCommand to file currentProcess
Xend sendCommand
X
Xfunction getReply
X  global thePrompt
X  global currentProcess
X  put false into done
X  put empty into reply
X  repeat until done
X    read from file currentProcess until the numToChar of 4
X    put the length of it - 1 into len
X    if len < 0 then
X      put true into done
X    else
X      if len > 0 then
X        if char len of it = thePrompt then
X          put true into done
X          put len - 1 into len
X          if len > 0 then
X            put reply & char 1 to len of it into reply
X          end if
X        else
X          put reply & char 1 to len of it into reply
X        end if
X      end if
X    end if
X  end repeat
X  return reply
Xend getReply
X
X
END_OF_hypertalk
if test 1554 -ne `wc -c <hypertalk`; then
    echo shar: \"hypertalk\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
Paul Anderson                      JANET: paul@uk.ac.ed.lfcs
LFCS, Dept. of Computer Science    UUCP:  ..!mcvax!ukc!lfcs!paul	
University of Edinburgh            ARPA:  paul%lfcs.ed.ac.uk@nsfnet-relay.ac.uk
Edinburgh EH9 3JZ, UK.             Tel:   031-667-1081 Ext 2788

paul@lfcs.ed.ac.uk (Paul Anderson) (09/28/89)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 2)."
# Contents:  aufs.diffs
# Wrapped by paul@uist on Mon Sep 25 09:38:35 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f aufs.diffs -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"aufs.diffs\"
else
echo shar: Extracting \"aufs.diffs\" \(28109 characters\)
sed "s/^X//" >aufs.diffs <<'END_OF_aufs.diffs'
X*** /export/src/master/cap/CAP-5.0/cap50/applications/aufs/Makefile	Tue May 17 18:40:42 1988
X--- Makefile	Fri Jun 30 17:29:02 1989
X***************
X*** 1,4 ****
X! # Makefile autoconfigured for a: \
X  	Standard BSD system on Tue May 17 13:40:41 EDT 1988
X  
X  
X--- 1,4 ----
X!  # Makefile autoconfigured for a: \
X  	Standard BSD system on Tue May 17 13:40:41 EDT 1988
X  
X  
X***************
X*** 39,45 ****
X  
X  # make sure that you define point getopt to att_getopt.o if your system
X  # doesn't have it builtin
X! GETOPT=att_getopt.o
X  
X  # This encodes the assumed location of certain directories
X  EXTRAS=../../extras
X--- 39,46 ----
X  
X  # make sure that you define point getopt to att_getopt.o if your system
X  # doesn't have it builtin
X! # GETOPT=att_getopt.o
X! GETOPT=
X  
X  # This encodes the assumed location of certain directories
X  EXTRAS=../../extras
X***************
X*** 49,60 ****
X  #
X  # End of configurable options
X  #
X! SRCS=afpos.c afpvols.c afpfile.c afpdir.c afpfork.c \
X  	afpmisc.c afpserver.c aufsicon.c abmisc2.c \
X  	afpdt.c afpdid.c afposenum.c  afpavl.c \
X  	afposfi.c afpgc.c afppasswd.c afposlock.c aufsv.c \
X  	afpudb.c afposncs.c
X! OBJS=afpos.o afpvols.o afpfile.o \
X  	afpmisc.o afpserver.o aufsicon.o abmisc2.o \
X  	afpdt.o afpdir.o afpfork.o afpdid.o afposenum.o afpavl.o \
X  	afposfi.o afpgc.o afppasswd.o aufsv.o \
X--- 50,61 ----
X  #
X  # End of configurable options
X  #
X! SRCS=afpos.c afproc.c afpvols.c afpfile.c afpdir.c afpfork.c \
X  	afpmisc.c afpserver.c aufsicon.c abmisc2.c \
X  	afpdt.c afpdid.c afposenum.c  afpavl.c \
X  	afposfi.c afpgc.c afppasswd.c afposlock.c aufsv.c \
X  	afpudb.c afposncs.c
X! OBJS=afpos.o afproc.o afpvols.o afpfile.o \
X  	afpmisc.o afpserver.o aufsicon.o abmisc2.o \
X  	afpdt.o afpdir.o afpfork.o afpdid.o afposenum.o afpavl.o \
X  	afposfi.o afpgc.o afppasswd.o aufsv.o \
X***************
X*** 67,73 ****
X  	${CC} $(LFLAGS) -o aufs aufs.o $(OBJS) $(CAPFILES) ${RENAME} \
X  		$(GETOPT) ${AFPLIB} ${CAPLIB} ${SLIB}
X  
X! newver: 
X  	/bin/sh aufs_vers.sh `cat aufs_vers` aufs_vers aufsv.c
X  	make all
X  
X--- 68,74 ----
X  	${CC} $(LFLAGS) -o aufs aufs.o $(OBJS) $(CAPFILES) ${RENAME} \
X  		$(GETOPT) ${AFPLIB} ${CAPLIB} ${SLIB}
X  
X! newver: aufs_vers.sh
X  	/bin/sh aufs_vers.sh `cat aufs_vers` aufs_vers aufsv.c
X  	make all
X  
X***************
X*** 91,99 ****
X  att_getopt.c:
X  	ln -s ${EXTRAS}/att_getopt.c
X  
X! afpos.o:	afpos.c
X  	${CC} ${OSDEFS} ${CFLAGS} -c afpos.c
X  
X  afposncs.o:	afposncs.c
X  	${CC} ${OSDEFS} ${CFLAGS} -c afposncs.c
X  
X--- 92,103 ----
X  att_getopt.c:
X  	ln -s ${EXTRAS}/att_getopt.c
X  
X! afpos.o:	afpos.c afppasswd.h afposncs.h afpgc.h afproc.h
X  	${CC} ${OSDEFS} ${CFLAGS} -c afpos.c
X  
X+ afproc.o:	afproc.c afproc.h
X+ 	${CC} ${OSDEFS} ${CFLAGS} -c afproc.c
X+ 
X  afposncs.o:	afposncs.c
X  	${CC} ${OSDEFS} ${CFLAGS} -c afposncs.c
X  
X***************
X*** 100,106 ****
X  afpudb.o:	afpudb.c
X  	${CC} ${CFLAGS} ${AFPUDB} -c afpudb.c
X  
X! aufs.o:	aufs.c
X  	${CC} ${CFLAGS} ${AUFSDEFS} -c aufs.c
X  
X  # Dependencies
X--- 104,110 ----
X  afpudb.o:	afpudb.c
X  	${CC} ${CFLAGS} ${AFPUDB} -c afpudb.c
X  
X! aufs.o:	aufs.c afps.h
X  	${CC} ${CFLAGS} ${AUFSDEFS} -c aufs.c
X  
X  # Dependencies
X***************
X*** 108,113 ****
X--- 112,121 ----
X  				$I/netat/aberrors.h $I/netat/abqueue.h \
X  				$I/netat/afp.h \
X  				afpvols.h $I/netat/afpcmd.h 
X+ afproc.o:        afproc.c       $I/netat/appletalk.h \
X+ 				$I/netat/aberrors.h $I/netat/abqueue.h \
X+ 				$I/netat/afp.h \
X+ 				afpvols.h $I/netat/afpcmd.h 
X  afpudb.o:	afpudb.c	$I/netat/appletalk.h afpudb.h
X  afpfork.o:      afpfork.c       $I/netat/appletalk.h $I/netat/aberrors.h \
X  				$I/netat/abqueue.h $I/netat/afp.h \
X***************
X*** 161,163 ****
X--- 169,173 ----
X  afppasswd.o:    afppasswd.c	$I/netat/sysvcompat.h afppasswd.h
X  afposncs.o:	afposncs.c	$I/netat/appletalk.h $I/netat/afp.h \
X  				afposncs.h afps.h
X+ %:		RCS/%,v
X+ 		co -r$(VERSION) $@
X*** /export/src/master/cap/CAP-5.0/cap50/applications/aufs/afpmisc.c	Thu May 19 20:19:45 1988
X--- afpmisc.c	Fri Jun 30 17:32:17 1989
X***************
X*** 1,7 ****
X  /*
X!  * $Author: cck $ $Date: 88/02/23 17:16:17 $
X!  * $Header: afpmisc.c,v 1.9 88/02/23 17:16:17 cck Rel $
X!  * $Revision: 1.9 $
X  */
X  
X  /*
X--- 1,7 ----
X  /*
X!  * $Author: paul $ $Date: 89/06/06 10:33:34 $
X!  * $Header: /tmp_mnt/auto1b00053/paul/code/aufs/p2/RCS/afpmisc.c,v 1.9.1.1 89/06/06 10:33:34 paul Rel Locker: paul $
X!  * $Revision: 1.9.1.1 $
X  */
X  
X  /*
X***************
X*** 49,58 ****
X    {DBG_DEBG|DBG_SRVR,"Server"},
X    {DBG_DEBG|DBG_UNIX,"Unix"},
X    {DBG_DEBG|DBG_VOLS,"Volume"},
X    {DBG_DEBG,"debug"}
X  };
X  
X! #define DBTABN 11		/* size of debug table */
X  
X  char *DBLevelOpts()
X  {
X--- 49,59 ----
X    {DBG_DEBG|DBG_SRVR,"Server"},
X    {DBG_DEBG|DBG_UNIX,"Unix"},
X    {DBG_DEBG|DBG_VOLS,"Volume"},
X+   {DBG_DEBG|DBG_PROC,"Process"},
X    {DBG_DEBG,"debug"}
X  };
X  
X! #define DBTABN 12		/* size of debug table */
X  
X  char *DBLevelOpts()
X  {
X*** /export/src/master/cap/CAP-5.0/cap50/applications/aufs/afpos.c	Thu Aug 11 14:24:13 1988
X--- afpos.c	Fri Jun 30 17:29:57 1989
X***************
X*** 1,7 ****
X  /*
X!  * $Author: cck $ $Date: 88/05/13 09:19:18 $
X!  * $Header: afpos.c,v 1.81 88/05/13 09:19:18 cck Rel $
X!  * $Revision: 1.81 $
X  */
X  
X  /*
X--- 1,7 ----
X  /*
X!  * $Author: paul $ $Date: 89/06/08 16:05:55 $
X!  * $Header: /tmp_mnt/auto1b00053/paul/code/aufs/p2/RCS/afpos.c,v 1.81.1.3 89/06/08 16:05:55 paul Exp Locker: paul $
X!  * $Revision: 1.81.1.3 $
X  */
X  
X  /*
X***************
X*** 135,140 ****
X--- 135,141 ----
X  #include "afppasswd.h"			/* in case we are using privates */
X  #include "afposncs.h"
X  #include "afpgc.h"
X+ #include "afproc.h"
X  
X  #ifdef MAXBSIZE
X  # define IOBSIZE MAXBSIZE	/* set to max buf entry size by if there */
X***************
X*** 205,210 ****
X--- 206,217 ----
X  #endif
X  
X  import int errno;
X+ import PROCESS *FindProcess();
X+ import OSErr ProcOpen();
X+ import OSErr ProcWrite();
X+ import OSErr ProcRead();
X+ import OSErr ProcClose();
X+ import OSErr ProcDelete();
X  
X  /*
X   * AFPOS functions
X***************
X*** 533,539 ****
X   *  AccessDenied	User does not have the rights (specified in AFP spec).
X   *
X   */
X! OSErr
X  OSDelete(ipdir,idir,file)
X  IDirP ipdir, idir;
X  char *file;
X--- 540,546 ----
X   *  AccessDenied	User does not have the rights (specified in AFP spec).
X   *
X   */
X! export OSErr
X  OSDelete(ipdir,idir,file)
X  IDirP ipdir, idir;
X  char *file;
X***************
X*** 541,548 ****
X    int err;
X    char path[MAXPATHLEN];
X  
X!   OSfname(path,ipdir,file,F_DATA);	/* create data fork name */
X  
X    if (DBOSI)
X      printf("OSDelete file=%s\n",path);
X  
X--- 548,557 ----
X    int err;
X    char path[MAXPATHLEN];
X  
X!   OSfname(path,ipdir,NameOf(file),F_DATA);	/* create data fork name */
X  
X+   if (IsProcess(file)) return ProcDelete(path);
X+ 
X    if (DBOSI)
X      printf("OSDelete file=%s\n",path);
X  
X***************
X*** 556,562 ****
X      err = unix_rmdir(path);		/* delete the data file */
X      if (err != noErr)
X        return(err);
X!     (void) os_delete(ipdir,file,F_FNDR);	/* delete finder fork */
X      /* remove the dirid */
X      FModified(ipdir, file);
X      Idrdirid(ipdir, idir);		/* idir is invalid after this point */
X--- 565,571 ----
X      err = unix_rmdir(path);		/* delete the data file */
X      if (err != noErr)
X        return(err);
X!     (void) os_delete(ipdir,file,F_FNDR); /* delete finder fork */
X      /* remove the dirid */
X      FModified(ipdir, file);
X      Idrdirid(ipdir, idir);		/* idir is invalid after this point */
X***************
X*** 566,574 ****
X    err = unix_unlink(path);		/* rid the data file */
X    if (err != noErr)
X      return(err);
X!   (void) os_delete(ipdir,file,F_RSRC);	/* delete resource fork */
X!   (void) os_delete(ipdir,file,F_FNDR);	/* delete finder fork */
X!   FModified(ipdir, file);
X    return(noErr);
X  }
X  
X--- 575,583 ----
X    err = unix_unlink(path);		/* rid the data file */
X    if (err != noErr)
X      return(err);
X!   (void) os_delete(ipdir,NameOf(file),F_RSRC);	/* delete resource fork */
X!   (void) os_delete(ipdir,NameOf(file),F_FNDR);	/* delete finder fork */
X!   FModified(ipdir, NameOf(file));
X    return(noErr);
X  }
X  
X***************
X*** 687,697 ****
X   *
X   */
X  
X! OSErr
X  OSRename(pdir,from,to)
X  IDirP pdir;				/* parent directory id */
X  char *from,*to;				/* from and to file names */
X  {
X    return(os_move(pdir,from,pdir,to));	/* do the work */
X  }
X  
X--- 696,707 ----
X   *
X   */
X  
X! export OSErr
X  OSRename(pdir,from,to)
X  IDirP pdir;				/* parent directory id */
X  char *from,*to;				/* from and to file names */
X  {
X+   if (IsProcess(from) || IsProcess(to)) return(peInvalid);
X    return(os_move(pdir,from,pdir,to));	/* do the work */
X  }
X  
X***************
X*** 726,731 ****
X--- 736,742 ----
X  char *from;				/* from file name */
X  char *to;				/*  to file name is dest directory */
X  {
X+   if (IsProcess(from) || IsProcess(to)) return(peInvalid);
X    return(os_move(fpdir, from, tpdir, to));
X  }
X  
X***************
X*** 746,753 ****
X    int err,cerr;
X    int mo;
X  
X!   OSfname(fpath,fpdir,from,F_DATA);	/* build data file name */
X!   OSfname(tpath,tpdir,to,F_DATA);	/* for from and to files */
X  
X    if (DBOSI)
X      printf("OSRename from=%s, to=%s\n",fpath,tpath);
X--- 757,764 ----
X    int err,cerr;
X    int mo;
X  
X!   OSfname(fpath,fpdir,NameOf(from),F_DATA);	/* build data file name */
X!   OSfname(tpath,tpdir,NameOf(to),F_DATA);	/* for from and to files */
X  
X    if (DBOSI)
X      printf("OSRename from=%s, to=%s\n",fpath,tpath);
X***************
X*** 772,779 ****
X    if (!S_ISDIR(stb.st_mode)) {		/* directories have no rsrc fork */
X      unix_chmod(tpath, mo);		/* file: try to reset protection */
X      if (fpdir->flags & DID_RESOURCE) {
X!       OSfname(fpath,fpdir,from,F_RSRC);	/* build resource file names */
X!       OSfname(tpath,tpdir,to,F_RSRC);
X        err = unix_rename(fpath,tpath);	/* give unix a shot at it */
X        /* allow non-existant resource */
X        if (err != noErr && err != aeObjectNotFound) { /* error on rename? */
X--- 783,790 ----
X    if (!S_ISDIR(stb.st_mode)) {		/* directories have no rsrc fork */
X      unix_chmod(tpath, mo);		/* file: try to reset protection */
X      if (fpdir->flags & DID_RESOURCE) {
X!       OSfname(fpath,fpdir,NameOf(from),F_RSRC);	/* build resource file names */
X!       OSfname(tpath,tpdir,NameOf(to),F_RSRC);
X        err = unix_rename(fpath,tpath);	/* give unix a shot at it */
X        /* allow non-existant resource */
X        if (err != noErr && err != aeObjectNotFound) { /* error on rename? */
X***************
X*** 780,787 ****
X  	if (DBOSI)
X  	  printf("os_rename: failed %s for %s -> %s\n",
X  		 afperr(err),fpath,tpath);
X! 	OSfname(fpath,fpdir,from,F_DATA); /* try to rebuild */
X! 	OSfname(tpath,tpdir,to,F_DATA);
X  	cerr = unix_rename(tpath,fpath);	/* rename back to orignal */
X  	if (cerr != noErr && DBOSI)
X  	  printf("os_rename: cleanup failed\n");
X--- 791,798 ----
X  	if (DBOSI)
X  	  printf("os_rename: failed %s for %s -> %s\n",
X  		 afperr(err),fpath,tpath);
X! 	OSfname(fpath,fpdir,NameOf(from),F_DATA); /* try to rebuild */
X! 	OSfname(tpath,tpdir,NameOf(to),F_DATA);
X  	cerr = unix_rename(tpath,fpath);	/* rename back to orignal */
X  	if (cerr != noErr && DBOSI)
X  	  printf("os_rename: cleanup failed\n");
X***************
X*** 792,799 ****
X    }  
X  
X    if (fpdir->flags & DID_FINDERINFO) {
X!     OSfname(fpath,fpdir,from,F_FNDR);	/* build finder info file names */
X!     OSfname(tpath,tpdir,to,F_FNDR);
X      err = unix_rename(fpath,tpath);	/* give unix a shot at it */
X      if (err != noErr && DBOSI) {
X        printf("os_rename: failed %s for %s -> %s\n", afperr(err),fpath,tpath);
X--- 803,810 ----
X    }  
X  
X    if (fpdir->flags & DID_FINDERINFO) {
X!     OSfname(fpath,fpdir,NameOf(from),F_FNDR);/* build finder info file names */
X!     OSfname(tpath,tpdir,NameOf(to),F_FNDR);
X      err = unix_rename(fpath,tpath);	/* give unix a shot at it */
X      if (err != noErr && DBOSI) {
X        printf("os_rename: failed %s for %s -> %s\n", afperr(err),fpath,tpath);
X***************
X*** 800,806 ****
X      } else {
X        if (!S_ISDIR(stb.st_mode))
X  	unix_chmod(tpath, mo);		/* file: try to reset protection */
X!       OSSetMacFileName(tpdir, to);
X      }
X    } else
X      if (DBOSI)
X--- 811,817 ----
X      } else {
X        if (!S_ISDIR(stb.st_mode))
X  	unix_chmod(tpath, mo);		/* file: try to reset protection */
X!       OSSetMacFileName(tpdir, NameOf(to));
X      }
X    } else
X      if (DBOSI)
X***************
X*** 807,815 ****
X        printf("os_rename: no finder info to rename\n");
X  
X    if (S_ISDIR(stb.st_mode))		/* if a directory then need to */
X!     Idmove(fpdir,from,tpdir,to);	/*  change internal structure */
X  
X!   FModified(fpdir, from);	/* does an emodified */
X    /* EModified(fpdir); */
X    /* don't need to mark dest file as modified since mac won't let this */
X    /* happen */
X--- 818,826 ----
X        printf("os_rename: no finder info to rename\n");
X  
X    if (S_ISDIR(stb.st_mode))		/* if a directory then need to */
X!     Idmove(fpdir,NameOf(from),tpdir,NameOf(to)); /*change internal structure */
X  
X!   FModified(fpdir, NameOf(from));	/* does an emodified */
X    /* EModified(fpdir); */
X    /* don't need to mark dest file as modified since mac won't let this */
X    /* happen */
X***************
X*** 879,885 ****
X  OSClose(fd)
X  int fd;
X  {
X!   return(unix_close(fd));		/* return OSErr */
X  }
X  
X  /*
X--- 890,899 ----
X  OSClose(fd)
X  int fd;
X  {
X!   PROCESS *p;
X! 
X!   if (p=FindProcess(fd)) return ProcClose(p);
X!   else return(unix_close(fd));		/* return OSErr */
X  }
X  
X  /*
X***************
X*** 904,909 ****
X--- 918,924 ----
X  int trans_table_index;
X  {
X    register char c;
X+   PROCESS *p;
X    int cnt,i;
X  
X  #ifdef notdef
X***************
X*** 914,919 ****
X--- 929,937 ----
X    }
X  #endif
X  
X+   if (p=FindProcess(fd))
X+     return( ProcRead( p, r, reqcnt, rl ) );
X+ 
X    if (offs != *fpos)
X      lseek(fd,(off_t)offs,L_SET);
X  
X***************
X*** 978,983 ****
X--- 996,1002 ----
X   * unixtomax - if non-zero translate cr to lf on writes
X   *
X  */
X+ export OSErr
X  OSWrite(fd,wbuf,wlen,offs,flg,fpos,trans_table_index)
X  int fd;
X  byte *wbuf;
X***************
X*** 987,996 ****
X--- 1006,1018 ----
X  int trans_table_index;
X  {
X    int cnt;
X+   PROCESS *p;
X  
X    if (wlen == 0)			/* zero byte request? */
X      return(noErr);			/*  yes... no work */
X  
X+   if (p=FindProcess(fd)) return( ProcWrite( p, wbuf, wlen ) );
X+ 
X    if (flg == 0) {
X      if (offs != *fpos)
X        *fpos = lseek(fd,(off_t)offs,L_SET);
X***************
X*** 1077,1082 ****
X--- 1099,1106 ----
X    if (DBOSI)
X      printf("OSCreateDir: creating %s\n",name);
X  
X+   if (IsProcess(name)) return(peInvalid);
X+ 
X    err = unix_stat(pathstr(pdir),&stb);	/* get current protections */
X    mo = stb.st_mode & 0777;
X  
X***************
X*** 1120,1131 ****
X    struct stat buf;
X    time_t sometime;
X  
X!   OSfname(path,ipdir,fn,F_DATA);
X  
X    if (DBOSI)
X      printf("OSFileDirInfo on %s\n",path);
X  
X!   if (stat(path,&buf) != 0) {		/* file exists? */
X      if (idir)				/* was in directory tree? */
X        Idrdirid(ipdir, idir);		/* invalidate the entry then */
X      return(aeObjectNotFound);		/* no... */
X--- 1144,1155 ----
X    struct stat buf;
X    time_t sometime;
X  
X!   OSfname(path,ipdir,NameOf(fn),F_DATA);
X  
X    if (DBOSI)
X      printf("OSFileDirInfo on %s\n",path);
X  
X!   if (stat(path,&buf) != 0) {         /* file exists? */
X      if (idir)				/* was in directory tree? */
X        Idrdirid(ipdir, idir);		/* invalidate the entry then */
X      return(aeObjectNotFound);		/* no... */
X***************
X*** 1140,1157 ****
X  
X    fdp->fdp_bdate = 0;
X    fdp->fdp_zero = 0;			/* zero the zero byte (?) */
X! /*  strcpy(fdp->fdp_lname,fn);		/* copy long name */
X    if (idir == VolRootD(volid))
X      strcpy(fdp->fdp_lname, VolName(volid));
X    else
X!     ItoEName(fn,fdp->fdp_lname);
X  
X    if (S_ISDIR(buf.st_mode)) {		/* is this a directory? */
X      fdp->fdp_flg = FDP_DIRFLG;		/* yes... */
X!     return(OSDirInfo(ipdir,fn,fdp,&buf,volid));	/* fill in */
X    }
X    fdp->fdp_flg = 0;			/* otherwise a file */
X!   return(OSFileInfo(ipdir,fn,fdp,&buf)); /* fill in */
X  }
X  
X    
X--- 1164,1181 ----
X  
X    fdp->fdp_bdate = 0;
X    fdp->fdp_zero = 0;			/* zero the zero byte (?) */
X! /*  strcpy(fdp->fdp_lname,NameOf(fn));		/* copy long name */
X    if (idir == VolRootD(volid))
X      strcpy(fdp->fdp_lname, VolName(volid));
X    else
X!     ItoEName(NameOf(fn),fdp->fdp_lname);
X  
X    if (S_ISDIR(buf.st_mode)) {		/* is this a directory? */
X      fdp->fdp_flg = FDP_DIRFLG;		/* yes... */
X!     return(OSDirInfo(ipdir,NameOf(fn),fdp,&buf,volid));	/* fill in */
X    }
X    fdp->fdp_flg = 0;			/* otherwise a file */
X!   return(OSFileInfo(ipdir,NameOf(fn),fdp,&buf)); /* fill in */
X  }
X  
X    
X***************
X*** 1168,1173 ****
X--- 1192,1199 ----
X    word bm;
X    int nchild;
X  
X+   if (IsProcess(fn)) return(peInvalid);
X+ 
X    fdp->fdp_dbitmap &= DP_AUFS_VALID; /* truncate to findable */
X    bm = fdp->fdp_dbitmap;
X  
X***************
X*** 1279,1302 ****
X    char rpath[MAXPATHLEN];
X    word bm;
X  
X!   fdp->fdp_fbitmap &= FP_AUFS_VALID; /* truncate to aufs supported */
X    bm = fdp->fdp_fbitmap;		/* fetch file bitmap */
X  
X    if (DBDIR)
X!     printf("OSFileInfo on %s bm=%x\n",fn,bm);
X  
X    if (bm & FP_ATTR)			/* skip attr if not requested */
X!     OSGetAttr(ipdir,fn,&fdp->fdp_attr);
X  
X    if (bm & FP_FINFO)			/* skip finfo if not requested */
X!     OSGetFNDR(ipdir,fn,fdp->fdp_finfo);
X  
X    fdp->fdp_parms.fp_parms.fp_fileno = buf->st_ino;
X    fdp->fdp_parms.fp_parms.fp_dflen = buf->st_size;
X    fdp->fdp_parms.fp_parms.fp_rflen = 0;
X  
X    if (bm & FP_RFLEN) {
X!     OSfname(rpath,ipdir,fn,F_RSRC);	/* convert to rsrc name */
X      if (stat(rpath,&stb) != 0)		/* to figure size of resource fork */
X        return(noErr);
X      if (DBFIL)
X--- 1305,1329 ----
X    char rpath[MAXPATHLEN];
X    word bm;
X  
X!   fdp->fdp_fbitmap &= FP_AUFS_VALID;    /* truncate to aufs supported */
X    bm = fdp->fdp_fbitmap;		/* fetch file bitmap */
X  
X    if (DBDIR)
X!     printf("OSFileInfo on %s bm=%x\n",NameOf(fn),bm);
X  
X    if (bm & FP_ATTR)			/* skip attr if not requested */
X!     OSGetAttr(ipdir,NameOf(fn),&fdp->fdp_attr);
X  
X    if (bm & FP_FINFO)			/* skip finfo if not requested */
X!     OSGetFNDR(ipdir,NameOf(fn),fdp->fdp_finfo);
X  
X    fdp->fdp_parms.fp_parms.fp_fileno = buf->st_ino;
X    fdp->fdp_parms.fp_parms.fp_dflen = buf->st_size;
X    fdp->fdp_parms.fp_parms.fp_rflen = 0;
X+   fdp->fdp_parms.fp_parms.fp_rflen = 0;
X  
X    if (bm & FP_RFLEN) {
X!     OSfname(rpath,ipdir,NameOf(fn),F_RSRC);	/* convert to rsrc name */
X      if (stat(rpath,&stb) != 0)		/* to figure size of resource fork */
X        return(noErr);
X      if (DBFIL)
X***************
X*** 1319,1325 ****
X    char path[MAXPATHLEN];  
X    struct stat stb;
X  
X!   OSfname(path, ipdir, fn, type);
X    return(unix_stat(path, &stb));
X  }
X  
X--- 1346,1352 ----
X    char path[MAXPATHLEN];  
X    struct stat stb;
X  
X!   OSfname(path, ipdir, NameOf(fn), type);
X    return(unix_stat(path, &stb));
X  }
X  
X***************
X*** 1334,1339 ****
X--- 1361,1368 ----
X    struct stat stb;
X    int err;
X  
X+   if (IsProcess(fn)) return(noErr);
X+ 
X    OSfname(path,ipdir,fn,F_DATA);	/* unix file name */
X    if ((err = unix_stat(path,&stb)) != noErr) {
X      /* can't find it !!! */
X***************
X*** 1356,1361 ****
X--- 1385,1392 ----
X  {
X    word bm = fdp->fdp_fbitmap;
X  
X+   if (IsProcess(fn)) return(noErr);
X+ 
X    if (bm & (FP_FINFO|FP_ATTR))
X      OSSetFA(ipdir,fn,fdp->fdp_fbitmap,fdp);
X    return(noErr);
X***************
X*** 1367,1373 ****
X   * 
X   *
X  */
X! OSErr
X  OSSetDirParms(ipdir,fn,fdp)
X  IDirP ipdir;
X  char *fn;
X--- 1398,1404 ----
X   * 
X   *
X  */
X! export OSErr
X  OSSetDirParms(ipdir,fn,fdp)
X  IDirP ipdir;
X  char *fn;
X***************
X*** 1379,1384 ****
X--- 1410,1417 ----
X    DirParm *dp = &fdp->fdp_parms.dp_parms;
X    int flags;
X  
X+   if(IsProcess(fn)) return(peInvalid);
X+ 
X    if (fdp->fdp_dbitmap & (DP_FINFO|DP_ATTR))
X      OSSetFA(ipdir,fn,fdp->fdp_dbitmap,fdp);
X  
X***************
X*** 1433,1438 ****
X--- 1466,1474 ----
X  int len;
X  {
X    int err;
X+ 
X+   if (FindProcess(fd)) return(noErr);
X+ 
X    if (DBOSI)
X      printf("OSSetForklen: truncating file on file descriptor %d to %d\n",
X  	   fd,len);
X***************
X*** 1694,1700 ****
X    if (mode & OFK_MRD)
X      imode |= R_OK;
X  
X!   OSfname(path,idir,fn,F_DATA);		/* create unix style filename */
X    err = access(path,imode);
X    if (err == 0)
X      return(noErr);
X--- 1730,1736 ----
X    if (mode & OFK_MRD)
X      imode |= R_OK;
X  
X!   OSfname(path,idir,NameOf(fn),F_DATA);	/* create unix style filename */
X    err = access(path,imode);
X    if (err == 0)
X      return(noErr);
X***************
X*** 2060,2065 ****
X--- 2096,2103 ----
X    int mo;
X    int err;
X  
X+   if (IsProcess(spath) || IsProcess(dpath)) return (peInvalid);
X+ 
X    OSfname(spath,spdir,sfile,F_DATA);	/* create unix style name for data */
X    OSfname(dpath,dpdir,dfile,F_DATA);	/*  same for destination */
X  
X***************
X*** 2204,2215 ****
X    int err,derr,rerr,cerr,mo;
X    struct stat stb;
X  
X!   OSfname(path,pdir,file,F_DATA);	/* create data file name */
X  
X    if (DBOSI)
X      printf("OSCreateFile: creating %s with %s\n",path,
X  	   (delf) ? "OverWrite" : "No OverWrite");
X!   
X    err = unix_stat(pathstr(pdir),&stb);
X    if (err != noErr)
X      return(err);
X--- 2242,2255 ----
X    int err,derr,rerr,cerr,mo;
X    struct stat stb;
X  
X!   if (IsProcess(file)) return (peInvalid);
X  
X+   OSfname(path,pdir,file,F_DATA); /* create name */
X+ 
X    if (DBOSI)
X      printf("OSCreateFile: creating %s with %s\n",path,
X  	   (delf) ? "OverWrite" : "No OverWrite");
X! 
X    err = unix_stat(pathstr(pdir),&stb);
X    if (err != noErr)
X      return(err);
X***************
X*** 2230,2236 ****
X      return(derr);
X    }
X  
X!   OSfname(path,pdir,file,F_RSRC);	/* try creating resource fork */
X    rerr = unix_create(path,delf,mo);	/* ... */
X    if (rerr != noErr && rerr != aeObjectExists && rerr != aeObjectNotFound) {
X      if (DBOSI)
X--- 2270,2276 ----
X      return(derr);
X    }
X  
X!   OSfname(path,pdir,file,F_RSRC);/* try creating resource fork */
X    rerr = unix_create(path,delf,mo);	/* ... */
X    if (rerr != noErr && rerr != aeObjectExists && rerr != aeObjectNotFound) {
X      if (DBOSI)
X***************
X*** 2255,2262 ****
X    EModified(pdir);
X    return(noErr);
X  }
X-   
X  
X  export OSErr
X  OSOpenFork(pdir,file,mode,typ,fhdl)
X  IDirP pdir;				/* parent directory */
X--- 2295,2302 ----
X    EModified(pdir);
X    return(noErr);
X  }
X  
X+ 
X  export OSErr
X  OSOpenFork(pdir,file,mode,typ,fhdl)
X  IDirP pdir;				/* parent directory */
X***************
X*** 2268,2274 ****
X    char *ms;
X    int mo;
X  
X!   OSfname(path,pdir,file,typ);		/* expand name */
X  
X    if ((mode & ~(OFK_MRD|OFK_MWR)) != 0)
X      if (DBOSI)
X--- 2308,2314 ----
X    char *ms;
X    int mo;
X  
X!   OSfname(path,pdir,NameOf(file),typ); /* expand name */
X  
X    if ((mode & ~(OFK_MRD|OFK_MWR)) != 0)
X      if (DBOSI)
X***************
X*** 2288,2294 ****
X    if (DBOSI) 
X      printf("OSOpenFork: Opening %s for %s\n",path,ms);
X  
X!   return(unix_open(path,mo,fhdl));
X  }
X  
X  
X--- 2328,2335 ----
X    if (DBOSI) 
X      printf("OSOpenFork: Opening %s for %s\n",path,ms);
X  
X!   if (IsProcess(file)) return( ProcOpen( path, mo, fhdl ) );
X!   else return(unix_open(path,mo,fhdl));
X  }
X  
X  
X*** /export/src/master/cap/CAP-5.0/cap50/applications/aufs/afps.h	Thu May 19 20:20:07 1988
X--- afps.h	Fri Jun 30 17:29:12 1989
X***************
X*** 1,7 ****
X  /*
X!  * $Author: cck $ $Date: 88/05/13 09:24:04 $
X!  * $Header: afps.h,v 1.19 88/05/13 09:24:04 cck Rel $
X!  * $Revision: 1.19 $
X  */
X  
X  /*
X--- 1,7 ----
X  /*
X!  * $Author: paul $ $Date: 89/06/06 10:39:06 $
X!  * $Header: /tmp_mnt/auto1b00053/paul/code/aufs/p2/RCS/afps.h,v 1.19.1.1 89/06/06 10:39:06 paul Rel $
X!  * $Revision: 1.19.1.1 $
X  */
X  
X  /*
X***************
X*** 62,67 ****
X--- 62,68 ----
X  #define DBG_DEBG 00200		/* in debug */
X  #define DBG_UNIX 00400		/* debug unix routines */
X  #define DBG_ENUM 01000		/* debug directory enumerations */
X+ #define DBG_PROC 02000		/* debug processes */
X  
X  #define DBG_ALL (DBG_FILE|DBG_FORK|DBG_SRVR|DBG_VOLS| \
X  		 DBG_OSIN|DBG_DIRS|DBG_DESK|DBG_DEBG| \
X***************
X*** 78,83 ****
X--- 79,85 ----
X  #define DBDEB (afp_dbug & DBG_DEBG)
X  #define DBUNX (afp_dbug & DBG_UNIX)
X  #define DBENU (afp_dbug & DBG_ENUM)
X+ #define DBPRO (afp_dbug & DBG_PROC)
X  
X  /* afpdid.c */
X  
X*** /export/src/master/cap/CAP-5.0/cap50/applications/aufs/aufs.c	Thu Aug 11 14:10:26 1988
X--- aufs.c	Fri Jun 30 17:29:10 1989
X***************
X*** 1,7 ****
X  /*
X!  * $Author: cck $ $Date: 88/05/19 13:11:35 $
X!  * $Header: aufs.c,v 1.53 88/05/19 13:11:35 cck Rel $
X!  * $Revision: 1.53 $
X  */
X  
X  /*
X--- 1,7 ----
X  /*
X!  * $Author: paul $ $Date: 89/06/08 19:56:35 $
X!  * $Header: /tmp_mnt/auto1b00053/paul/code/aufs/p2/RCS/aufs.c,v 1.53.1.4 89/06/08 19:56:35 paul Exp $
X!  * $Revision: 1.53.1.4 $
X  */
X  
X  /*
X***************
X*** 69,74 ****
X--- 69,75 ----
X  char *mytod();			/* return tod */
X  
X  export int statflg = FALSE;	/* default is not to show stats */
X+ export int enableProcs = FALSE; /* default is not to allow process execution */
X  
X  private char *sysvolfile = NULL; /* system afpvols file */
X  private char *srvrname = NULL;
X***************
X*** 146,151 ****
X--- 147,155 ----
X  private int *ctp_stack;
X  private int ctp_stack_cnt;
X  
X+ import void ProcInit();
X+ import void ProcCleanup();
X+ 
X  usage(name)
X  char *name;
X  {
X***************
X*** 173,178 ****
X--- 177,183 ----
X    fprintf(stderr,"\t-S <n> limit responses to <n> packets\n");
X    fprintf(stderr,"\t-R <n> limit remote to sending <n> packets\n");
X    fprintf(stderr,"\t-X datafile of logged in users\n"); /* budd */
X+   fprintf(stderr,"\t-p to enable remote process code\n");
X    fprintf(stderr,"\nExample: %s -t 'bdelete irename' -a 'file fork dir' -s\n",
X  	  name);
X    exit(1);
X***************
X*** 204,210 ****
X    extern char *optarg;
X    extern int optind;
X    
X!   while ((c = getopt(argc,argv,"a:d:D:n:N:t:sV:U:G:P:c:l:z:S:R:X:")) != EOF) {
X      switch (c) {
X      case 'z':
X        strncpy(zonetorun, optarg, 32);
X--- 209,215 ----
X    extern char *optarg;
X    extern int optind;
X    
X!   while ((c = getopt(argc,argv,"a:d:D:n:N:t:sV:U:G:P:c:l:z:S:R:X:p")) != EOF) {
X      switch (c) {
X      case 'z':
X        strncpy(zonetorun, optarg, 32);
X***************
X*** 247,252 ****
X--- 252,260 ----
X      case 'P':
X        passwdlookaside = optarg;
X        break;
X+     case 'p':
X+       enableProcs = TRUE;
X+       break;
X      case 'G':
X        guestid = optarg;
X        break;
X***************
X*** 551,556 ****
X--- 559,565 ----
X  #endif
X  	signal(SIGHUP, dienow);	/* superior signaled us to shutdown */
X  	mypid = getpid();
X+ 	ProcInit();             /* Initialize process code */
X  #ifndef NOSHUTDOWNCODE
X  	setpgrp(0, parent_pid);	/* set our process group */
X  	dying();		/* are we dying? if so, handle it*/
X***************
X*** 558,564 ****
X        }
X        sigsetmask(mask);
X  #ifndef DEBUGFORK
X!     } else pid = 0;
X  #endif
X    } while (pid != 0);		/* pid = 0 implies inferior process */
X  
X--- 567,576 ----
X        }
X        sigsetmask(mask);
X  #ifndef DEBUGFORK
X!     } else {
X!       pid = 0;
X!       ProcInit();
X!     }
X  #endif
X    } while (pid != 0);		/* pid = 0 implies inferior process */
X  
X***************
X*** 588,593 ****
X--- 600,606 ----
X      SPGetRequest(cno,buf,mcs,&reqref,&type,&rlen,&comp);
X      while (comp > 0) { abSleep(sectotick(60),TRUE); }
X      if (comp == SessClosed || comp == ParamErr) {
X+       ProcCleanup();            /* Kill any processes owned by the session */
X        log("Session (%d) closed",cno);
X        clearuserlogin();			/* budd */
X        return;
X***************
X*** 824,832 ****
X    /* Try closing just in case */
X    SPCloseSession(cno, 3, 2, &comp); /* 3 times, .5 seconds */
X    while (comp > 0) { abSleep(30, TRUE); } /* close down if we can */
X    exit(0);
X  }
X- 
X  #ifndef NOSHUTDOWNCODE
X  
X  /*
X--- 837,846 ----
X    /* Try closing just in case */
X    SPCloseSession(cno, 3, 2, &comp); /* 3 times, .5 seconds */
X    while (comp > 0) { abSleep(30, TRUE); } /* close down if we can */
X+   /* Kill any active processes */
X+   ProcCleanup();
X    exit(0);
X  }
X  #ifndef NOSHUTDOWNCODE
X  
X  /*
END_OF_aufs.diffs
if test 28109 -ne `wc -c <aufs.diffs`; then
    echo shar: \"aufs.diffs\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
Paul Anderson                      JANET: paul@uk.ac.ed.lfcs
LFCS, Dept. of Computer Science    UUCP:  ..!mcvax!ukc!lfcs!paul	
University of Edinburgh            ARPA:  paul%lfcs.ed.ac.uk@nsfnet-relay.ac.uk
Edinburgh EH9 3JZ, UK.             Tel:   031-667-1081 Ext 2788