#
# Makefile for customs agent and its clients.
#
# $Id: Makefile,v 1.85 1999/06/29 21:13:24 stolcke Exp $ ICSI (Berkeley)
#
# Copyright (c) 1988, 1989 by the Regents of the University of California
# Copyright (c) 1988, 1989 by Adam de Boor
# Copyright (c) 1989 by Berkeley Softworks
#
# Permission to use, copy, modify, and distribute this
# software and its documentation for any non-commercial purpose
# and without fee is hereby granted, provided that the above copyright
# notice appears in all copies.  The University of California,
# Berkeley Softworks and Adam de Boor make no representations about
# the suitability of this software for any purpose.  It is provided
# "as is" without express or implied warranty.
#

#
# Owner of the various binaries
#
OWNER		= $$USER

#
# ETCDIR is where the system-control clients and the daemon itself go.
# USRLIBDIR is where the customs library (archive) goes.
# INCLUDEDIR is where the header files belonging to the customs library go.
#
ETCDIR		= /usr/local/etc
USRLIBDIR	= /usr/local/lib
INCLUDEDIR	= /usr/local/include/customs

#
# Strip installed binaries
#
STRIP		= -s

#
# Install flags for user clients that can do no harm.
#
BINMODE		= -m 755 -o $(OWNER) $(STRIP)
SCRIPTMODE	= -m 755 -o $(OWNER)
#
# Install flags for exporting clients.  If USE_RESERVED_PORTS was enabled in
# config.h, these need to be suid root.
#
XBINMODE	= -m 4755 -o root $(STRIP)
#
# Install flags the deamon and for control programs in $(ETCDIR).
# The latter can be usefully run by normal users, but critical operations
# will only be allowed if run as root.  Therefore they should probably NOT
# be suid root.
#
ETCMODE		= -m 755 -o root $(STRIP)
#
# Install flags for the customs library and header files
#
ARCMODE		= -m 644 -o $(OWNER) 
HDRMODE		= -m 444 -o $(OWNER)

#
# Shell commands run after binary installation is complete.  May be used
# to fix up anything that needs special handling.
#
POSTINSTALL	= true

#
# Include PMake common description
#
DEPFILE		?= dependencies.mk
#include	"$(.CURDIR)/../common.mk"

#
# Local changes to installation, etc.
#
#if exists($(.CURDIR)/../config.mk)
#include	"$(.CURDIR)/../config.mk"
#endif

#
# Additional path definitions
#
.PATH.h		: $(INCLUDE) $(.CURDIR)/..
.PATH.a		: $(SPRITEDIR)/$(MAKEOBJDIR) $(SPRITEDIR)
.PATH.c		: test

#
# Export anywhere
#
.EXPORT:
.SHELL:

CC		?= cc
LDCC		?= $(CC)
MACHFLAGS	?=
OPTIMIZE	?= -g -O

CFLAGS		+= $(OPTIMIZE) $(MACHFLAGS) -I.

#ifdef PURIFY
LDCC		:= purify $(LDCC) $(STATICFLAG)
CFLAGS		+= -DPURIFY
#endif

#ifdef SYSV
CFLAGS		+= -DSYSV
#endif
#ifdef SVR4
CFLAGS		+= -DSVR4
#endif

#
# If there's no /dev/kbd from which Customs can derive the user's idle time
# (this is intended for workstations only), don't do idle time checking.
#
#CFLAGS		+= -DNO_IDLE

#
# If making a profiled version, give the proper flags and configure pieces of
# code properly. Note this isn't done on a sun because the last time I profiled
# pmake on a sun, it died in the profiling code...
#
#if make(prof) && !defined(sun)
CFLAGS		+= -pg -DPROF
#endif

#
# Objects that make up the Customs daemon itself. OSOBJ is the object file
# that contains the OS functions to determine the state of the machine.
#	os-sunos4 should be used for suns running SunOS4.0 or higher
#	os-sunos5 should be used for suns running SunOS5.0 or higher
#	os-bsd can be used for most unixes that are based on the Berkeley
#	    Software Distribution, as well as some derived systems
#	    (NeXT, HP-UX, IRIX, SunOS).
#	os-default contains dummy functions and provides rudimentary idle
#	    time support for generic UNIX systems.
#
OSOBJ		= os-bsd.o
CUSTOMSOBJS 	= customs.o mca.o avail.o import.o election.o xdr.o \
		  log.o swap.o $(OSOBJ)
SYSLIBS		?= 

#
# List of source files used by depend and tags targets
#
ALLSRCS		= $(CUSTOMSOBJS:N-l*:S/.o$/.c/g) \
		  $(RPCOBJS:N-l*:S/.o$/.c/g) \
		  host.c export.c importquota.c reginfo.c logd.c cctrl.c
ALLHDRS		= config.h customs.h customsInt.h log.h rpc.h xlog.h

LIBCUSTOMS	= libcustoms.a
LIBHDRS		= $(.CURDIR)/customs.h $(.CURDIR)/rpc.h \
		  $(LSTDIR)/lst.h $(INCLUDE)/sprite.h
# These are actually only required to use some of the library functions
# independently from customs -- don't install them, to avoid clutter.
#LIBHDRS	+= $(.CURDIR)/xlog.h $(INCLUDE)/*.h

#
# System dependencies
#
#ifdef sun
# ifdef SVR4
CFLAGS		+= -DHAVE_VSYSLOG
#  if exists(/usr/include/sys/loadavg.h)
CFLAGS		+= -DHAVE_GETLOADAVG
#  endif
OSOBJ		= os-sunos5.o -lkvm -lelf
SYSLIBS		+= -lsocket -lnsl
# elif exists(/usr/lib/libkvm.a)
OSOBJ		= os-sunos4.o -lkvm
STATICFLAG	?= -Bstatic
PUREFLAG	?= -n -Bdynamic
# endif
#if exists(/usr/lib/libbsdmalloc.a)
SYSLIBS		+= -lbsdmalloc
#endif
#elifdef ultrix
CUSTOMSOBJS	+= getusershell.o
#elifdef next
#CFLAGS		+= -bsd -DSIGRET=int
#elifdef hpux
CFLAGS		+= -I/usr/include -I/etc/conf/h # so we can use -D_KERNEL
#elifdef sgi
CFLAGS		+= -DHAVE_VSYSLOG
# if exists(/usr/lib64/mips3)
CFLAGS		+= -DIRIX64
# The following flags may need to be adjusted to match the proc structure
# actually used by the running kernel (see <sys/proc.h>).
CFLAGS		+= -D_HIBERNATORII -D_SHAREII -D_VM_WS_SWAPPING
# endif
CUSTOMSOBJS	+= getusershell.o
#ifdef SVR4
CFLAGS		+= -D_KMEMUSER
# if !exists(/lib32)
OSOBJ		+= -lmld		# for nlist
# else
OSOBJ		+= -lelf		# for nlist
# endif
#else
OSOBJ		+= -lmld
SYSLIBS		+= -lsun -lc_s		# for xdr functions and shared libc
#endif
#elifdef osf
# all o.k.
#elifdef bsdi
CFLAGS		+= -DHAVE_SA_LEN
SYSLIBS		+= -lrpc
#elifdef linux
CFLAGS		+= -DHAVE_VSYSLOG
OSOBJ		= os-linux.o
#elifdef SYSV
OSOBJ		= os-default.o
CUSTOMSOBJS	+= getusershell.o
#endif

STATICFLAG	?= 
PUREFLAG	?= 

#
# Files required by all clients to talk to the Customs agent
#
SIGOBJS		= sigList.o sigFromHost.o sigFromName.o \
		  sigToHost.o sigToName.o
LIBOBJS		= customsInit.o customsA2L.o customsAvail.o customsError.o \
		  customsExport.o customsHost.o customsHostA.o \
		  customsHname.o customsInfo.o customsL2A.o customsMWB.o \
		  customsMaster.o customsNorm.o customsPError.o customsPing.o \
		  customsCheck.o
RPCOBJS		= $(LIBOBJS) $(SIGOBJS) rpc.o xlog.o

#
# All clients made by this makefile
#
USERCLIENTS	= reginfo
XUSERCLIENTS	= export pmake
SYSCLIENTS	= importquota cctrl logd
CLIENTS		= $(USERCLIENTS) $(XUSERCLIENTS) $(SYSCLIENTS)
SCRIPTS		= rexport

#
all		: customs $(CLIENTS) $(LIBCUSTOMS) myconfig.h

#
# Simple installation rule -- not all systems allow one to install many files
# at once, so do it in a 'for' loop
#
install		:: install-bin install-lib

install-bin	:: .NOEXPORT customs $(CLIENTS)
	test -d $(DESTDIR)$(ETCDIR) || mkdir $(DESTDIR)$(ETCDIR)
	-mv $(DESTDIR)$(ETCDIR)/customs $(DESTDIR)$(ETCDIR)/customs~
	for i in $(SYSCLIENTS) customs; do
	    $(INSTALL) $(ETCMODE) $i $(DESTDIR)$(ETCDIR)/`basename $i`
	done
	test -d $(DESTDIR)$(BINDIR) || mkdir $(DESTDIR)$(BINDIR)
	if test ! -f $(DESTDIR)$(BINDIR)/pmake.nocustoms; then
	   -mv $(DESTDIR)$(BINDIR)/pmake $(DESTDIR)$(BINDIR)/pmake.nocustoms
	else
	   -mv $(DESTDIR)$(BINDIR)/pmake $(DESTDIR)$(BINDIR)/pmake~
	fi
	for i in $(USERCLIENTS); do
	    $(INSTALL) $(BINMODE) $i $(DESTDIR)$(BINDIR)/`basename $i`
	done
	for i in $(XUSERCLIENTS); do
	    $(INSTALL) $(XBINMODE) $i $(DESTDIR)$(BINDIR)/`basename $i`
	done
	for i in $(SCRIPTS); do
	    $(INSTALL) $(SCRIPTMODE) $(.CURDIR)/$i $(DESTDIR)$(BINDIR)/`basename $i`
	done
	$(POSTINSTALL)

install-lib	:: .NOEXPORT $(LIBCUSTOMS) myconfig.h
	test -d $(DESTDIR)$(USRLIBDIR) || mkdir $(DESTDIR)$(USRLIBDIR)
	$(INSTALL) $(ARCMODE) $(LIBCUSTOMS) $(DESTDIR)$(USRLIBDIR)/$(LIBCUSTOMS)
	$(RANLIB) $(DESTDIR)$(USRLIBDIR)/$(LIBCUSTOMS)
	test -d $(DESTDIR)$(INCLUDEDIR) || mkdir $(DESTDIR)$(INCLUDEDIR)
	for i in $(LIBHDRS); do
	    $(INSTALL) $(HDRMODE) $i $(DESTDIR)$(INCLUDEDIR)/`basename $i`
	done
	$(INSTALL) $(HDRMODE) myconfig.h $(DESTDIR)$(INCLUDEDIR)/config.h

myconfig.h: $(.CURDIR)/config.h $(.CURDIR)/../unix/config.h
	sed -e '/^#include/r $(.CURDIR)/../unix/config.h' \
		-e '/^#include/d' $(.CURDIR)/config.h > $(.TARGET)

#
# Bump version number whenever any part of customs is updated.
# version.h is included in customs.c.  We cannot let version.h depend
# on customs.o because that would create a cyclic dependency.
# Don't export to get the hostname in the version string right.
#
version.h	: customs.c $(CUSTOMSOBJS:Ncustoms.o) $(RPCOBJS) \
		  $(LISTLIB) $(SPRITELIB) \
		  .NOEXPORT
		sh $(.CURDIR)/../etc/newvers.sh
customs.o	: version.h

#
# Rule to link all clients. Very simple
#
LINK		: .USE .EXPORTSAME
	$(LDCC) $(CFLAGS) $(LDFLAGS) $(.ALLSRC) -o $(.TARGET)
SLINK		: .USE .EXPORTSAME
	$(LDCC) $(CFLAGS) $(LDFLAGS) $(STATICFLAG) $(.ALLSRC) -o $(.TARGET)
PLINK		: .USE .EXPORTSAME
	$(LDCC) $(CFLAGS) $(LDFLAGS) $(PUREFLAG) $(.ALLSRC) -o $(.TARGET)

# link customs as pure executable so doesn't depend on server binary
customs		: $(CUSTOMSOBJS) $(LIBCUSTOMS) $(SYSLIBS)	PLINK
host		: host.o $(LIBCUSTOMS) $(SYSLIBS)		LINK
# link export statically to speed up programs that use it in slave mode
export		: export.o $(LIBCUSTOMS) $(SYSLIBS)		SLINK
importquota	: importquota.o $(LIBCUSTOMS) $(SYSLIBS)	LINK
reginfo		: reginfo.o $(LIBCUSTOMS) $(SYSLIBS)		LINK
logd		: logd.o xdr.o $(LIBCUSTOMS) $(SYSLIBS)		LINK
prof		: pmake
pmake		: $(OBJS) $(LIBCUSTOMS) $(SYSLIBS) 		LINK
cctrl		: cctrl.o $(LIBCUSTOMS) $(SYSLIBS)		LINK

# These were used for testing and benchmarking only.
#
#nulltest	: test/nulltest.c $(RPCOBJS)			LINK
#rpctest	: test/rpctest.c rpc.o				LINK
#rpcsrv		: test/rpcsrv.c rpc.o				LINK

# We need to run .END commands for libcustoms.a BEFORE it is used in
# linking.  So do a recursive make libcustoms.a at the top level.
#if !make($(LIBCUSTOMS))

$(LIBCUSTOMS):	$(RPCOBJS:M*.o) $(SPRITELIB) $(LISTLIB) .NOEXPORT .MAKE
	cd $(.CURDIR); $(MAKE) -l $(LIBCUSTOMS)

#else # not making libcustoms

#
# The customs library contains everything needed to build customs clients.
# This includes the entire contents of the sprite and lst libraries.
#
$(LIBCUSTOMS)	:: $(RPCOBJS:M*.o) .EXPORTSAME
	...
	$(AR) cr $(.TARGET) $(.OODATE)
	$(RANLIB) $(.TARGET)

$(LIBCUSTOMS)	:: $(SPRITELIB) .EXPORTSAME
	test -d sprite-objs || mkdir sprite-objs
	(cd sprite-objs; $(AR) x ../$(SPRITEDIR)/$(MAKEOBJDIR)/$(SPRITELIB:S/-l/lib/).a)
	...
	$(AR) cr $(LIBCUSTOMS) sprite-objs/[!_]*
	$(RANLIB) $(LIBCUSTOMS)
	$(RM) -r sprite-objs

$(LIBCUSTOMS)	:: $(LISTLIB) .EXPORTSAME
	test -d lst-objs || mkdir lst-objs
	(cd lst-objs; $(AR) x ../$(LSTDIR)/$(MAKEOBJDIR)/$(LISTLIB:S/-l/lib/).a)
	...
	$(AR) cr $(LIBCUSTOMS) lst-objs/[!_]*
	$(RANLIB) $(LIBCUSTOMS)
	$(RM) -r lst-objs

.END		: .EXPORTSAME

#endif # making libcustoms

#
# test program for Customs_NormPath()
#
testNorm	: customsNorm.c $(LIBCUSTOMS) .EXPORTSAME
	$(CC) $(CFLAGS) -DSTANDALONE -o $@ $(.ALLSRC) $(LIBCUSTOMS) $(SYSLIBS)

clean		:: .NOEXPORT
	$(RM) customs host testNorm $(CLIENTS)
	$(RM) $(LIBCUSTOMS) myconfig.h *.o *.bak
	$(RM) -r sprite-objs lst-objs

#
# Declare additional sources for which dependencies should be generated
#
depend		: $(ALLSRCS) .NOEXPORT

tags		: $(ALLSRCS) $(ALLHDRS)

#ifdef exists($(DEPFILE))
#include "$(DEPFILE)"
#endif

#
# Some targets for testing
#
#TESTCMD	= hostname
TESTCMD		= /bin/sleep 10
TESTTARGETS = 0 1 2 3 4 5 6 7 8 9
test:	$(TESTTARGETS)
	:

$(TESTTARGETS):
	$(TESTCMD)

testrm: test.c
	touch testrm
	$(TESTCMD)
