changeset 3781:41d7a70cdf1d

PSARC 2006/647 PPD Manager 5100134 print/rfc1179 ends up by default in "offline" state 6236968 No documented way to add PPD file to ppdcache 6527759 Need to delete legacy print/cleanup service 6529794 lpsched not started after first local printer is added
author ceastha
date Thu, 08 Mar 2007 17:32:28 -0800
parents 26abf9fe811a
children d53b92e6d144
files usr/src/cmd/lp/lib/oam/msg.source usr/src/cmd/print/Makefile usr/src/cmd/print/bsd-sysv-commands/rfc1179.xml usr/src/cmd/print/ppdmgr/Makefile usr/src/cmd/print/ppdmgr/ppd-cache-update usr/src/cmd/print/ppdmgr/ppd-cache-update.xml usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/InstallLocalPPD.rawhlp usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/InstallNetworkPPD.rawhlp usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/ModifyPPD.rawhlp usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/PrintManagerSettings.rawhlp usr/src/cmd/print/printmgr/com/sun/admin/pm/server/pmMisc.java usr/src/cmd/print/scripts/Makefile usr/src/cmd/print/scripts/getmakes usr/src/cmd/print/scripts/getmodels usr/src/cmd/print/scripts/getppdfile usr/src/cmd/print/scripts/getppds usr/src/cmd/print/scripts/lpadmin usr/src/cmd/print/scripts/manufaliases usr/src/cmd/print/scripts/ppdfilename2mmp usr/src/cmd/print/scripts/ppdmgr usr/src/cmd/svc/profile/generic_limited_net.xml usr/src/cmd/svc/profile/generic_open.xml usr/src/cmd/svc/shell/netservices.sh usr/src/lib/libsecdb/exec_attr.txt usr/src/lib/print/mod_ipp/ipp-listener.xml usr/src/pkgdefs/SUNWppm/preremove usr/src/pkgdefs/SUNWppm/prototype_com usr/src/pkgdefs/SUNWpsr/postinstall usr/src/pkgdefs/SUNWpsr/preinstall usr/src/pkgdefs/SUNWpsr/prototype_com usr/src/tools/scripts/bfu.sh
diffstat 31 files changed, 2491 insertions(+), 215 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/lp/lib/oam/msg.source	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/lp/lib/oam/msg.source	Thu Mar 08 17:32:28 2007 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -23,7 +22,7 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -854,7 +853,11 @@
 	"Either use another name, or remove the conflicting form using `lpforms'."
 E_ADM_NOPPD
 	"The ppd \"%s\" does not exist."
-	"Use the command\n    ls /usr/lib/lp/model/ppd\nto find the list of known printer ppd definitions."
+	"Use the command\n    find <PPD file repository> -type f\n"
+	"where <PPD file repository> is one or more of the following:\n"
+	"    /usr/share/ppd/*/*/\n    /usr/share/local/ppd/*/*/\n"
+	"    /opt/share/ppd/*/*/\n    /var/lp/ppd/*/*/\n"
+	"to find the list of known printer ppd definitions."
 
 #endif
 
--- a/usr/src/cmd/print/Makefile	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/Makefile	Thu Mar 08 17:32:28 2007 -0800
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -37,6 +37,7 @@
 		lpset		\
 		conv_fix	\
 		printer-info	\
+		ppdmgr		\
 		bsd-sysv-commands
 
 SUBDIRS = $(PRINT_SUBDIRS) $(JAVA_SUBDIRS)
--- a/usr/src/cmd/print/bsd-sysv-commands/rfc1179.xml	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/bsd-sysv-commands/rfc1179.xml	Thu Mar 08 17:32:28 2007 -0800
@@ -21,7 +21,7 @@
 
  CDDL HEADER END
 
- Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  Use is subject to license terms.
 
  ident	"%Z%%M%	%I%	%E% SMI"
@@ -39,7 +39,7 @@
     type='service'
     version='1'>
 
-    	<create_default_instance enabled='true' />
+    	<create_default_instance enabled='false' />
 
 	<restarter>
 		<service_fmri value='svc:/network/inetd:default' />
@@ -48,7 +48,7 @@
 	<dependency
 		name='lpsched'
 		grouping='require_all'
-		restart_on='error'
+		restart_on='refresh'
 		type='service'>
 		<service_fmri value='svc:/application/print/server' />
 	</dependency>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/print/ppdmgr/Makefile	Thu Mar 08 17:32:28 2007 -0800
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+MANIFEST=		ppd-cache-update.xml
+SVCMETHOD=		ppd-cache-update
+
+include		../Makefile.sp
+
+ROOTMANIFESTDIR=	$(ROOTSVCAPPLICATIONPRINT)
+$(ROOTMANIFEST):=	FILEMODE= 444
+
+ROOTVARLP=		$(ROOTVAR)/lp
+ROOTVARLPPPD=		$(ROOTVARLP)/ppd
+ROOTVARLPPPDCACHES=	$(ROOTVARLPPPD)/caches
+
+$(ROOTVARLP):=		OWNER= lp
+$(ROOTVARLP):=		DIRMODE= 775
+
+.KEEP_STATE:
+
+all:
+install:	$(ROOTMANIFEST) $(ROOTSVCMETHOD) \
+		$(ROOTVARLP) $(ROOTVARLPPPD) $(ROOTVARLPPPDCACHES)
+check:		$(CHKMANIFEST)
+clean:
+clobber:
+lint:
+
+$(ROOTVARLP) $(ROOTVARLPPPD) $(ROOTVARLPPPDCACHES):
+	$(INS.dir)
+
+include		$(SRC)/cmd/Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/print/ppdmgr/ppd-cache-update	Thu Mar 08 17:32:28 2007 -0800
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+
+. /lib/svc/share/smf_include.sh
+
+case "$1" in
+'start')
+	if [ -x /usr/sbin/ppdmgr ] ; then
+		/usr/sbin/ppdmgr -u -R all -L all
+	fi
+	;;
+*)
+	echo "Usage: $0 start"
+	exit 1
+	;;
+esac
+exit $SMF_EXIT_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/print/ppdmgr/ppd-cache-update.xml	Thu Mar 08 17:32:28 2007 -0800
@@ -0,0 +1,90 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+-->
+<!--
+ Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ Use is subject to license terms.
+
+	ident	"%Z%%M%	%I%	%E% SMI"
+
+	NOTE:  This service manifest is not editable; its contents will
+	be overwritten by package or patch operations, including
+	operating system upgrade.  Make customizations in a different
+	file.
+-->
+
+<service_bundle type='manifest' name='SUNWppm:ppd-cache-update'>
+
+<service
+	name='application/print/ppd-cache-update'
+	type='service'
+	version='1'>
+
+	<create_default_instance enabled='false' />
+
+	<single_instance />
+
+	<!--
+	  This service writes to/reads from /tmp, /var, and /usr.
+	-->
+	<dependency
+		name='filesystem'
+		grouping='require_all'
+		restart_on='none'
+		type='service'>
+		<service_fmri value='svc:/system/filesystem/minimal' />
+	</dependency>
+
+	<exec_method
+		type='method'
+		name='start'
+		exec='/lib/svc/method/ppd-cache-update start'
+		timeout_seconds='0'>
+	</exec_method>
+
+	<exec_method
+		type='method'
+		name='stop'
+		exec=':true'
+		timeout_seconds='3'>
+	</exec_method>
+
+	<property_group name='startd' type='framework'>
+		<propval name='duration' type='astring' value='transient' />
+	</property_group>
+
+	<stability value='Unstable' />
+
+	<template>
+		<common_name>
+			<loctext xml:lang='C'>
+				ppd cache update
+			</loctext>
+		</common_name>
+		<documentation>
+			<manpage title='ppdmgr' section='1M'
+				manpath='/usr/share/man' />
+		</documentation>
+	</template>
+</service>
+
+</service_bundle>
--- a/usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/InstallLocalPPD.rawhlp	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/InstallLocalPPD.rawhlp	Thu Mar 08 17:32:28 2007 -0800
@@ -3,9 +3,8 @@
     CDDL HEADER START
 
     The contents of this file are subject to the terms of the
-    Common Development and Distribution License, Version 1.0 only
-    (the "License").  You may not use this file except in compliance
-    with the License.
+    Common Development and Distribution License (the "License").
+    You may not use this file except in compliance with the License.
 
     You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 
     CDDL HEADER END
 
--- Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+-- Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 -- Use is subject to license terms.
 --
 -- ident	"%Z%%M%	%I%	%E% SMI"
@@ -80,7 +79,12 @@
 <p>
 
 <b> Printer Driver:</b>
-    Specifies the printer driver to use with this printer.
+    Specifies the printer driver to use with this printer.  The label
+    name followed in parentheses by one of the following letters
+representing the repository in which the printer driver information resides:
+U (user supplied printer information), A (administrator supplied printer
+information), V (vendor supplied printer information), or S (system supplied
+printer information), precedes the name of the Printer Driver.
 <p>
 
 <b> Fault Notification:</b> 
--- a/usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/InstallNetworkPPD.rawhlp	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/InstallNetworkPPD.rawhlp	Thu Mar 08 17:32:28 2007 -0800
@@ -3,9 +3,8 @@
     CDDL HEADER START
 
     The contents of this file are subject to the terms of the
-    Common Development and Distribution License, Version 1.0 only
-    (the "License").  You may not use this file except in compliance
-    with the License.
+    Common Development and Distribution License (the "License").
+    You may not use this file except in compliance with the License.
 
     You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 
     CDDL HEADER END
 
--- Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+-- Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 -- Use is subject to license terms.
 --
 -- ident	"%Z%%M%	%I%	%E% SMI"
@@ -73,7 +72,12 @@
 <p>
 
 <b> Printer Driver:</b>
-    Specifies the printer driver to use with this printer.
+    Specifies the printer driver to use with this printer.  The label
+    name followed in parentheses by one of the following letters
+representing the repository in which the printer driver information resides:
+U (user supplied printer information), A (administrator supplied printer
+information), V (vendor supplied printer information), or S (system supplied
+printer information), precedes the name of the Printer Driver.
 <p>
 
 
--- a/usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/ModifyPPD.rawhlp	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/ModifyPPD.rawhlp	Thu Mar 08 17:32:28 2007 -0800
@@ -3,9 +3,8 @@
     CDDL HEADER START
 
     The contents of this file are subject to the terms of the
-    Common Development and Distribution License, Version 1.0 only
-    (the "License").  You may not use this file except in compliance
-    with the License.
+    Common Development and Distribution License (the "License").
+    You may not use this file except in compliance with the License.
 
     You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 
     CDDL HEADER END
 
--- Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+-- Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 -- Use is subject to license terms.
 --
 -- ident	"%Z%%M%	%I%	%E% SMI"
@@ -76,7 +75,12 @@
 <p>
 
 <b> Printer Driver:</b>
-    Specifies the printer driver to use with this printer.
+    Specifies the printer driver to use with this printer.  The label
+    name followed in parentheses by one of the following letters
+representing the repository in which the printer driver information resides:
+U (user supplied printer information), A (administrator supplied printer
+information), V (vendor supplied printer information), or S (system supplied
+printer information), precedes the name of the Printer Driver.
 <p>
 
 
--- a/usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/PrintManagerSettings.rawhlp	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/PrintManagerSettings.rawhlp	Thu Mar 08 17:32:28 2007 -0800
@@ -1,4 +1,29 @@
 <TITLE> Print Manager Settings </TITLE> 
+<!--
+    CDDL HEADER START
+
+    The contents of this file are subject to the terms of the
+    Common Development and Distribution License (the "License").
+    You may not use this file except in compliance with the License.
+
+    You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+    or http://www.opensolaris.org/os/licensing.
+    See the License for the specific language governing permissions
+    and limitations under the License.
+
+    When distributing Covered Code, include this CDDL HEADER in each
+    file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+    If applicable, add the following below this CDDL HEADER, with the
+    fields enclosed by brackets "[]" replaced with your own identifying
+    information: Portions Copyright [yyyy] [name of copyright owner]
+
+    CDDL HEADER END
+
+-- Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+-- Use is subject to license terms.
+--
+-- ident	"%Z%%M%	%I%	%E% SMI"
+-->
 <!-- Tag=Overview --> 
 
 <CONTENT>
@@ -35,7 +60,16 @@
 <b> Use PPD files: </b> 
 When configuring local printers, PPD files may be used to describe the
 printer. If selected, the New Attached Printer and New Network Printer
-screens offer the selection of printer Make, Model, and PPD file.
+screens offer the selection of printer Make, Model, and Printer Driver
+from matching PPD files.  Duplicate entries may be displayed from
+PPD files in different labels within different PPD file repositories
+that represent suppliers of the PPD files.  Thus, the label name
+associated with the PPD file, and one of the following letters,
+within parentheses, representing the repository in which the printer
+driver information resides: U (user supplied printer information),
+A (administrator supplied printer information), V (vendor supplied
+printer information), or S (system supplied printer information),
+precedes the name of the Printer Driver.
 
 <p>
 The default is on.
--- a/usr/src/cmd/print/printmgr/com/sun/admin/pm/server/pmMisc.java	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/printmgr/com/sun/admin/pm/server/pmMisc.java	Thu Mar 08 17:32:28 2007 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -22,7 +21,7 @@
 /*
  * ident	"%Z%%M%	%I%	%E% SMI"
  *
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  *
  * Miscellaneous functions which don't apply to printer object
@@ -40,7 +39,7 @@
 
     public static boolean isppdCachefile()
     {
-	File ppdcache = new File("/usr/lib/lp/model/ppd/ppdcache");
+	File ppdcache = new File("/var/lp/ppd/ppdcache");
 	return (ppdcache.isFile());
     }
 
--- a/usr/src/cmd/print/scripts/Makefile	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/scripts/Makefile	Thu Mar 08 17:32:28 2007 -0800
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -31,14 +31,18 @@
 
 ROOTPRINTLIB = 		$(ROOTLIB)/print
 ROOTLIBLPBIN =		$(ROOTLIBLP)/bin
+ROOTVARLP =		$(ROOTVAR)/lp
+ROOTVARLPPPD =		$(ROOTVARLP)/ppd
 
 $(ROOTVARSPOOLPRINT)	:= OWNER=root
+$(ROOTVARLP)		:= OWNER=lp
+$(ROOTVARLP)		:= DIRMODE=0775
 
 OWNER =			root
 GROUP =			lp
 FILEMODE =		0755
 
-MSGFILES =              lpadmin
+MSGFILES =              lpadmin ppdmgr
 POFILE =                scripts.po
 
 PROG =			conv_lp conv_lpd Makefile.yp
@@ -46,7 +50,7 @@
 $(ROOTLIBPRINTPROG)	:= FILEMODE=0555
 $(ROOTPRINTLIB)/Makefile.yp		:= FILEMODE=0444
 
-USRSBINPROG=		lpsystem lpadmin
+USRSBINPROG=		lpsystem lpadmin ppdmgr
 ROOTUSRSBINPROG=	$(USRSBINPROG:%=$(ROOTUSRSBIN)/%)
 $(ROOTUSRSBINPROG)		:= FILEMODE=555
 
@@ -56,6 +60,12 @@
 $(ROOTPCONF)		:= GROUP=sys
 $(ROOTPCONF)		:= FILEMODE=644
 
+MANUFALIASES= 		manufaliases
+ROOTMANUFALIASES=	$(MANUFALIASES:%=$(ROOTVARLPPPD)/%)
+$(ROOTMANUFALIASES)	:= OWNER=root
+$(ROOTMANUFALIASES)	:= GROUP=lp
+$(ROOTMANUFALIASES)	:= FILEMODE=444
+
 PPDPROGS=	 	getmakes getmodels getppdfile getppds ppdfilename2mmp	
 ROOTPPDPROGS=		$(PPDPROGS:%=$(ROOTLIBLPBIN)/%)
 $(ROOTPPDPROGS)		:= OWNER=root
@@ -69,13 +79,16 @@
 
 all :			$(PROG) 
 
-$(ROOTLIB)/print/% $(ROOTINIT_D)/%:	%
+$(ROOTLIB)/print/%:	%
 	$(INS.file)
 
 $(ROOTLIBLPBIN)/%: %
 	$(INS.file)
 
-$(ROOTINIT_D) $(ROOTUSRSBIN) $(ROOTVARSPOOLPRINT):
+$(ROOTVARLPPPD)/%: %
+	$(INS.file)
+
+$(ROOTUSRSBIN) $(ROOTVARSPOOLPRINT) $(ROOTVARLP) $(ROOTVARLPPPD):
 	$(INS.dir)
 
 $(ROOTLIB)/lpadmin:
@@ -104,11 +117,13 @@
 	$(RM) $@ $(POFILE).i
 	mv messages.po $(POFILE)
 
-install:		$(ROOTINIT_D) $(ROOTLNKPROGS) \
+install:		$(ROOTLNKPROGS) \
 			$(ROOTLIBPRINTPROG) $(ROOTSTARTPROG) \
 			$(ROOTUSRSBIN) $(ROOTUSRSBINPROG) \
 			$(ROOTVARSPOOLPRINT) $(ROOTPCONF) \
-			$(ROOTPPDPROGS) $(LIBLINKS)
+			$(ROOTPPDPROGS) $(LIBLINKS) \
+			$(ROOTVARLP) $(ROOTVARLPPPD) \
+			$(ROOTMANUFALIASES)
 
 $(SYMLINKS1):
 	$(RM) $@; $(SYMLINK) ../sbin/$(SBINPROG1) $@
--- a/usr/src/cmd/print/scripts/getmakes	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/scripts/getmakes	Thu Mar 08 17:32:28 2007 -0800
@@ -3,9 +3,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,24 +19,19 @@
 #
 # CDDL HEADER END
 #
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
 
 #
 # get a list of the Manufacturers from the ppdcache
 #
 
-if [[ -f /usr/lib/lp/model/ppd/ppdcache ]]; then
-	/bin/cat /usr/lib/lp/model/ppd/ppdcache |
-			nawk '{FS=":"; print $1}' |
-			nawk '{print $1}' |
-			/bin/sort -u
-			
-	exit 0
-else
-	exit 1
-fi
+[[ -f /var/lp/ppd/ppdcache ]] || exit 1
+/bin/cat /var/lp/ppd/ppdcache |
+    nawk '{FS=":"; print $1}' |
+    nawk '{print $1}' |
+    /bin/sort -u
+exit 0
--- a/usr/src/cmd/print/scripts/getmodels	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/scripts/getmodels	Thu Mar 08 17:32:28 2007 -0800
@@ -3,9 +3,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,24 +19,27 @@
 #
 # CDDL HEADER END
 #
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
 
 #
 # get a list of the Models for this Model from the ppdcache
 #
+# Input:
+#	Manufacturer	(Note: printmgr passes only the first word
+#	Lexmark		of the manufacturer name)
+# Output:
+#	Manufacturer Model
+#	Lexmark Optra Color 1200
 
 if [[ $# -lt 1 ]]; then
         exit 1
 fi
 
-if [[ -f /usr/lib/lp/model/ppd/ppdcache ]]; then
-	/bin/grep ^$1 /usr/lib/lp/model/ppd/ppdcache | nawk '{FS=":"; print $2}' | uniq 
-	exit 0
-else
-	exit 1
-fi
+cachefile=/var/lp/ppd/ppdcache
+[[ -f $cachefile ]] || exit 1
+/bin/grep "^$1" $cachefile | nawk '{FS=":"; print $2}' | uniq 
+exit 0
--- a/usr/src/cmd/print/scripts/getppdfile	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/scripts/getppdfile	Thu Mar 08 17:32:28 2007 -0800
@@ -3,9 +3,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,41 +19,70 @@
 #
 # CDDL HEADER END
 #
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
 
 #
 # Get the path/ppdfilename for this ppd NickName
 # Input:
-#	make: model: ppd:
-#	PrintersRus: ABC Model 1234: Foomatic/Postscript (recommended):
+#	make: model: ppdlabel: ppd:
+#	PrintersRus: ABC Model 1234: SUNWfoomatic(S): Foomatic/Postscript (recommended):
 #
 
-if [[ $# -lt 3 ]]; then
+#
+# Returns the full path to the repository associated with
+# the repository letter found between parenthesis in the
+# extended PPD label.
+#
+# $1	- Extended PPD label
+#
+rep_path()
+{
+	case "$(expr \"$1\" : ".*(\(.*\)).*")" in
+	"S")
+		echo "/usr/share/ppd"
+		;;
+	"V")
+		echo "/opt/share/ppd"
+		;;
+	"A")
+		echo "/usr/local/share/ppd"
+		;;
+	"U")
+		echo "/var/lp/ppd"
+		;;
+	esac
+}
+
+if [[ $# -lt 4 ]]; then
         exit 1
 fi
 
-if [[ -f /usr/lib/lp/model/ppd/ppdcache ]]; then
-	typeset make=$(echo $* | /usr/bin/nawk '{FS=":"; print $1}')
-	# strip leading blanks
-	typeset model=$(echo $* | /usr/bin/nawk '{FS=":"; print $2}' |
-			sed -e 's/^[ ]*//')
-	typeset ppd=$(echo $* | /usr/bin/nawk '{FS=":"; print $3}' |
-			sed -e 's/^[ ]*//')
+[[ -f /var/lp/ppd/ppdcache ]] || exit 1
+make=$(echo $* | /usr/bin/nawk '{FS=":"; print $1}')
+# strip leading blanks
+model=$(echo $* | /usr/bin/nawk '{FS=":"; print $2}' |
+    /bin/sed -e 's/^[ ]*//')
+extppdlabel=$(echo $* | /usr/bin/nawk '{FS=":"; print $3}' |
+    /bin/sed -e 's/^[ ]*//')
+ppd=$(echo $* | /usr/bin/nawk '{FS=":"; print $4}' |
+    /bin/sed -e 's/^[ ]*//')
 
-	# Do not use ":" with $make. printmgr collapses manufacturer name
-	# to first word, ie PrintersRus and PrintersRus International become
-	# PrintersRus
-	/bin/grep "${make}" /usr/lib/lp/model/ppd/ppdcache | 
-	/bin/grep "${model}:" |
-	/bin/grep "${ppd}:"  |
-	nawk '{FS=":"; print $4}' 
+#
+# Do not use ":" with $make. printmgr collapses manufacturer name
+# to first word, ie PrintersRus and PrintersRus International become
+# PrintersRus.  The full path to the PPD file will be the 6th
+# colon separated entry in the ppdcache entry.  If the format
+# of a ppdcache entry changes, then this will need to be modified
+# also.
+#
+/bin/grep "${make}" /var/lp/ppd/ppdcache | 
+    /bin/grep "${model}:" |
+    /bin/grep "${ppd}:"  |
+    /bin/grep "$(rep_path ${extppdlabel})/${extppdlabel%\(*}" |
+    /usr/bin/nawk '{FS=":"; print $6}' 
 
-	exit 0
-else
-	exit 1
-fi
+exit 0
--- a/usr/src/cmd/print/scripts/getppds	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/scripts/getppds	Thu Mar 08 17:32:28 2007 -0800
@@ -3,9 +3,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,33 +19,88 @@
 #
 # CDDL HEADER END
 #
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
 
 #
 # get a list of the Models for this Model from the ppdcache
 #
 
+# Input:
+#	make model
+#	HP OfficeJet 4200
+# Output:
+#	<label>(<repository letter>): <driver>
+#	userlabel(U): Foomatic/hpijs (recommended)
+#	SUNWhpijs(S): Foomatic/hpijs (recommended)
+
+SaveIFS="$IFS"
+NoSpaceTabIFS='
+'
+SEP=": "
+
+#
+# Return cache entries matching the specified make
+# and model from the specified cache file.
+#
+# $1	- Make
+# $2	- Model
+# $3	- cachefile
+ppd_make_entries()
+{
+	for hit in $(/bin/grep "${1}" "${3}" | /bin/grep "${2}")
+	do
+		echo "${hit#*:*:}"
+	done
+}
+
 if [[ $# -lt 2 ]]; then
         exit 1
 fi
 
-typeset model
+cachefile=/var/lp/ppd/ppdcache
+[[ -f $cachefile ]] || exit 1
+make=$1
+shift
+model="$*"
+system=
+vendor=
+admin=
+user=
 
-if [[ -f /usr/lib/lp/model/ppd/ppdcache ]]; then
-	typeset make=$1
-	shift
-	
-	/bin/grep $make /usr/lib/lp/model/ppd/ppdcache |
-	/bin/grep "$*:" |
-	nawk '{FS=":"; print $3}' 
+#
+# Ensure each ppdcache entry is processed as a single string
+# otherwise it would be split up by spaces.
+#
+IFS="$NoSpaceTabIFS"
+for pentry in $(ppd_make_entries "${make}" "${model}" "${cachefile}")
+do
+	IFS="$SaveIFS"
+	ppdpath="${pentry##*:}"
+	ppdlpath="${ppdpath%/*/*}"
+	ppdlabel="${ppdlpath##*/}"
+	driver="${pentry%%:*}"
 
-	exit 0
-else
-	exit 1
-fi
+	case "${ppdpath}" in
+	"/usr/share/ppd/"*)
+		system="${system}${ppdlabel}(S)${SEP}${driver}\n"
+		;;
+	"/opt/share/ppd/"*)
+		vendor="${vendor}${ppdlabel}(V)${SEP}${driver}\n"
+		;;
+	"/usr/local/share/ppd/"*)
+		admin="${admin}${ppdlabel}(A)${SEP}${driver}\n"
+		;;
+	"/var/lp/ppd/"*)
+		user="${user}${ppdlabel}(U)${SEP}${driver}\n"
+		;;
+	esac
+	IFS="$NoSpaceTabIFS"
+done
+
+IFS="$SaveIFS"
+echo "${user}${admin}${vendor}${system}"
+exit 0
--- a/usr/src/cmd/print/scripts/lpadmin	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/scripts/lpadmin	Thu Mar 08 17:32:28 2007 -0800
@@ -37,6 +37,7 @@
 LPSTAT=/usr/bin/lpstat
 LPADMIN=/usr/lib/lp/local/lpadmin
 COMM=/usr/bin/comm
+PPDMGR=/usr/sbin/ppdmgr
 
 HOST=$(/bin/uname -n)
 exit_code=0
@@ -100,6 +101,28 @@
 	done
 }
 
+# Call the ppdmgr utility to add a new PPD file to the system.
+#
+# $1  - path to PPD file
+# $2  - label name (optional)
+add_new_ppd_file() {
+	# Add new ppd file and echo full path it was actually saved to
+	ppdmgrcmd="${PPDMGR} -a ${1} -w"
+
+	ppderrfile=/tmp/lpadminerror.$$
+	ppd_file=$(${ppdmgrcmd} 2>${ppderrfile})
+	ppdmgrrc=$?
+	if [[ -s "${ppderrfile}" ]] ; then
+		print -n "lpadmin: " 1>&2
+		cat ${ppderrfile} 1>&2
+		rm -f ${ppderrfile} >/dev/null 2>&1
+		if [[ ${ppdmgrrc} -ne 0 ]] ; then
+			exit 1
+		fi
+	fi
+	rm -f ${ppderrfile} >/dev/null 2>&1
+}
+
 #
 # Execution begins here
 #
@@ -154,6 +177,9 @@
 	D)
 		description="${OPTARG}"
 	;;
+	n)
+		ppd_file="${OPTARG}"
+	;;
 	p)
 		if [[ -n "${delete}" ]] ; then
 			usage
@@ -271,15 +297,26 @@
 		2>/dev/null) >${PRE}
 
 	# if there are no printers configured, enable LP service(s)
-	[[ -s "${PRE}" ]] && lp_config_service enable
+	[[ ! -s "${PRE}" ]] && lp_config_service enable
 
 	# add filters to LP service
 	lp_config_filters
 
+	# add new ppd file to PPD file repositories
+	if [[ -n "${ppd_file}" && -x ${PPDMGR} ]] ; then
+		add_new_ppd_file "${ppd_file}"
+	fi
+
 	# modify LP destination(s)
 	CMD=${LPADMIN}
 	while [[ -n "$*" ]] ; do	# to deal with multi-word arguments
 		CMD="$CMD \"$1\""
+		# replace the ppd_file originally specified with the -n option
+		# with the one returned from call to ppdmgr
+		if [[ "${1}" = "-n" ]] ; then
+			CMD="$CMD \"${ppd_file}\""
+			shift
+		fi
 		shift
 	done
 	case "$CMD" in
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/print/scripts/manufaliases	Thu Mar 08 17:32:28 2007 -0800
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+Canon:Canon Inc.
+Dymo:Dymo-CoStar
+Epson
+HP:hewlett-packard
+Minolta:minolta-qms
+Okidata:oki:OKI DATA CORP
+Xerox
+Lexmark:Lexmark International
--- a/usr/src/cmd/print/scripts/ppdfilename2mmp	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/print/scripts/ppdfilename2mmp	Thu Mar 08 17:32:28 2007 -0800
@@ -3,9 +3,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,64 +19,82 @@
 #
 # CDDL HEADER END
 #
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+
+#
+# Get the make/model/nickname as well as the repository/label from ppdfilename
 #
 
+# Input
+#	ppdfilename
+#	/var/lp/ppd/user/HP/foo.ppd.gz
+# Output
+#	make
+#	model
+#	label(repository letter): driver
 #
-# Get the make/model/nickname from ppdfilename
+#	Lexmark
+#	IBM Page Printer 3112
+#	foomatic(L): Foomatic/hpijs
 #
 
 if [[ $# -lt 1 ]]; then
         exit 1
 fi
 
-if [[ -f /usr/lib/lp/model/ppd/ppdcache ]]; then
-
-    ppdfile=`/bin/grep $1 /usr/lib/lp/model/ppd/ppdcache`
+cachefile=/var/lp/ppd/ppdcache
+[[ -f $cachefile ]] || exit 1
 
-    if [[ -z "$ppdfile" ]]; then
-
-	# Perhaps this is an old configuration file 
-	# look for ppd file in new directories
+cacheentry=$(/bin/grep "$1" $cachefile)
+[[ -n "$cacheentry" ]] || exit 1
 
-	# Get last two fields from arg1: full path/filename of ppd
-	# file. Separate with /.
-	# arg1: /usr/lib/lp/model/ppd/<MANU>/<filename>
-
-	manufile=`echo $1 | /bin/nawk -F/ '{ print $7 "/"  $8 }`
+#
+# Retrieve the manufacturer (make)
+# Use only the first word in manufacturer entry
+#
+manuf=$(echo "$cacheentry" | 
+nawk '{FS=":"; print $1}' |
+nawk '{print $1}')
 
-	# search for ppd file in all the directories under system 
-	# Use the first one found
+# Retrieve the model
+model=$(echo "$cacheentry" | nawk '{FS=":"; print $2}')
 
-	for dir in /usr/lib/lp/model/ppd/system/*; do
-		if [[ -d "$dir" ]]; then
-			target=$dir/$manufile
-			found=`/bin/grep $target /usr/lib/lp/model/ppd/ppdcache`
+# Retrieve the driver
+driver=$(echo "$cacheentry" | nawk '{FS=":"; print $3}')
 
-			if [[ -z "$ppdfile" &&  -n "$found" ]]; then
-				ppdfile=$found
-			fi
-		
-
-		fi 
-	done
-			
-    fi 	
+#
+# Retrieve the PPD path.  Parse the PPD path to get the
+# label path and to figure out the repository letter
+# associated with the label path.  Note:
+# the PPD file name is the 6th colon separated entry
+# in the cache entry.  This is may need to be modified if the
+# format changes.
+#
+ppdpath=$(echo "$cacheentry" | /bin/nawk '{FS=":"; print $6}' )
+manupath=$(/bin/dirname "$ppdpath")
+labelpath=$(/bin/dirname "$manupath")
 
-    if [[ -z "$ppdfile" ]]; then
-		exit 1
-    else
-		# Use only first word in manufacturer entry
-		echo $ppdfile | 
-		nawk '{FS=":"; print $1}' |
-		nawk '{print $1}'
+case "$labelpath" in
+/usr/share/ppd/*)
+	repltr=S
+		;;
+/opt/share/ppd/*)
+	repltr=V
+	;;
+/usr/local/share/ppd/*)
+	repltr=A
+	;;
+/var/lp/ppd/*)
+	repltr=U
+	;;
+esac
 
-		echo $ppdfile | 
-		nawk '{FS=":"; print $2; print $3}'
-		exit 0
-    fi
-fi
+[[ -n "${repltr}" ]] || exit 1
+echo "${manuf}\n${model}"
+echo "$(/bin/basename "$labelpath")(${repltr}): $driver"
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/print/scripts/ppdmgr	Thu Mar 08 17:32:28 2007 -0800
@@ -0,0 +1,1758 @@
+#!/bin/ksh 
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+#
+# Description: Script to generate the Solaris printmgr 'ppdcache' file from the
+#              ppd files installed in the given ppd database directory
+#
+# ppdmgr -a <ppd_filename_path> [ -L <label> ] [-w]
+# ppdmgr -g <ppd_filename_path> [ -L <label> ] [ -R <ppd_repository> ]
+# ppdmgr -r [ -L <label> ] [ -R <ppd_repository> ]
+# ppdmgr -u [ -L <label> ] [ -R <ppd_repository> ]
+#
+# Options:
+#		-a <ppd_filename_path>	- Add a new PPD file to the specified
+#					label in the "user" repository, and
+#					updates to the "user" repository
+#					in the ppdcache.
+#		-g <ppd_filename_path>	- Generate a cache file entry
+#					for the specified PPD file
+#					on standard out.
+#		-L <label>		- Label name.  <label>
+#					can be any characters from the
+#					portable character set, however
+#					may not contain a semi-colon (':').
+#					The following are the defaults
+#					for <label> for each option:
+#					OPTION	DEFAULT LABEL
+#					------	-------------
+#					-a	<label> from <ppd_filename_path>
+#						if <ppd_filename_path>
+#						is from a known repository,
+#						otherwise defaults to "user".
+#					-g	<label> from <ppd_filename_path>
+#						if <ppd_filename_path>
+#						is from a known repository,
+#						otherwise defaults to "user".
+#					-r	all
+#					-u	all
+#					The following are reserved labels:
+#					caches		- may never be specified
+#					ppdcache	- may never be specified
+#					manufaliases	- may never be specified
+#					all		- applies specified
+#							action to all labels
+#							in a repository.
+#							Can only be specified
+#							with -r or -u.
+#					SUNW*		- anything starting with
+#							SUNW is reserved for
+#							use by Sun, but not
+#							prohibited.
+#		-r			- Rebuild the cache information for the
+#					specified label in the specified
+#					repository.  Similar to -u, however,
+#					the cache file is removed to force an
+#					update to the ppdcache.
+#		-R <ppd_repository>	- PPD repository name.
+#					Defaults to "user".
+#					The following are the possible
+#					values for <ppd_repository> and
+#					location in the system:
+#					REP	LOCATION
+#					---	--------
+#					user	/var/lp/ppd
+#					admin	/usr/local/share/ppd
+#					vendor	/opt/share/ppd
+#					system	/usr/share/ppd
+#					all	all repositories
+#
+#					Note: When specified with the -a option
+#					only "user" and "admin" are valid.
+#					"vendor", "system", and "all" will be
+#					considered reserved.
+#		-u			- Update the PPD cache information
+#					for the specified label in the specified
+#					repository if needed.  If the cache
+#					update was required, then the updated
+#					cache information is reflected in
+#					the ppdcache.
+#		-w			- Display full path of where the
+#					ppd file is located on the system.
+#					Only valid with -a, otherwise the 
+#					option is ignored.
+#
+# If -a, -g, -r, or -u are specified on the command line, only the last action
+# specified will be performed.
+#
+# Cache file entry format:
+#	<ModifiedManufacturerName>:<Model>:<NickName>:<1284DeviceIDManufacturer>:<1284DeviceIDModel>:<FullPPDFilePath>
+#	HP:HP DeskJet 450:Foomatic/hpijs (recommended):dj450:hp:/usr/share/ppd/HP/HP-DeskJet_450-hpijs.ppd.gz
+#
+
+PATH=/bin:/usr/bin:/usr/sbin export PATH
+set -o noclobber
+
+TEXTDOMAIN="SUNW_OST_OSCMD"
+export TEXTDOMAIN
+
+#
+# Generates debug output for calling routine.
+# If calling routine's name is passed in, then
+# will also generate the name of the calling routine.
+#
+# $1	- Name of calling routine
+debugger()
+{
+	[[ ${debug} -eq 1 ]] || return 1
+	if [[ -n "${1}" ]] ; then
+		echo "In ${1}..." 1>&2
+	fi
+	return 0
+}
+
+#
+# Set the ownership and permissions on a file.
+#
+# $1	- Mode
+# $2	- Owner:Group
+# $3	- Full path to file
+#
+set_perms()
+{
+	/bin/chmod -f ${1} "${3}" >/dev/null 2>&1
+	/bin/chown -f ${2} "${3}" >/dev/null 2>&1
+}
+
+#
+# Create administrator repository directories, /usr/local/share/ppd,
+# if needed. This is a special case a Solaris doesn't deliver
+# /usr/local/share and it has different permissions than the
+# user repository.
+#	
+# $1	- destination repository name
+#
+create_adminrep_dirs()
+{
+	if debugger "check_adminrep_dirs" ; then
+		set -x
+	fi
+
+	# Only create administrator repository directories, if needed.
+	[[ "${1}" = "${ADMIN}" ]] || return 0
+
+	# Check /usr/local/share/ppd
+	[[ ! -d "${ADMINREP}" ]] || return 0
+
+	# Check /usr/local/share
+	admpar=$(/bin/dirname "${ADMINREP}")
+	if [[ ! -d "${admpar}" ]] ; then
+
+		# Check /usr/local
+		admppar=$(/bin/dirname "${admpar}")
+		if [[ ! -d "${admppar}" ]] ; then
+			make_dir ${DIRMODE} ${ADMINOWNER} "${admppar}" || \
+			    return 1
+		fi
+		make_dir ${DIRMODE} ${ADMINOWNER} "${admpar}" || return 1
+	fi
+	make_dir ${DIRMODE} ${ADMINOWNER} ${ADMINREP} || return 1
+	return 0
+}
+
+#
+# Returns full path to PPD file that was added to the system.
+#
+# $1	- Full path to source PPD file
+# $2	- PPD file name
+# $3	- Full path to repository
+# $4	- Repository name
+# $5	- Label name
+#
+# Return codes:
+#	0	- File successfully added
+#	1	- Error
+#	2	- Duplicate file already exists
+#
+add_ppd()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	verify_ppd_file "${1}"
+	if [[ $? -ne 0 ]] ; then
+		gettext "invalid PPD file: ${1}" 2>/dev/null
+		return 3
+	fi
+
+	# The destination path can now be set
+	dstlabelpath="${3}/${5}"
+	dstmanufpath="${dstlabelpath}/${modmanuf}"
+	dstpath="${dstmanufpath}/${2}"
+
+	#
+	# If a version (either compressed or not compressed) of the PPD
+	# file exists in the destination in the label/repository,
+	# then just return as there no work to be done.
+	dst_copy_path=$(variant_copy "${1}" "${dstpath}" "${6}" "${ppdfname}")
+	ap_rc=$?
+	if [[ ${ap_rc} -ne 0 ]] ; then
+		echo "${dst_copy_path}"
+		return ${ap_rc}
+	fi
+		
+	#
+	# Can only add a PPD file to the "user" or "admin" repository.
+	# Note: this check is here instead of at the top of this
+	# function as we don't want to cause an error if a user
+	# specifies the same repository and label as a the specified
+	# ppd file and the repository of the specified ppd file
+	# exists in a known repository.
+	#
+	if [[ "${4}" != "${USER}" && "${4}" != "${ADMIN}" ]] ; then
+		gettext "invalid PPD file repository name: ${4}" 2>/dev/null
+		return 3
+	fi
+
+	# Ensure destination directories exist
+	if ! create_adminrep_dirs ${4} ${DIRMODE} ${ADMINOWNER} || \
+	    ! make_dir ${DIRMODE} ${DIROWNER} "${3}" || \
+	    ! make_dir ${DIRMODE} ${DIROWNER} "${dstlabelpath}" || \
+	    ! make_dir ${DIRMODE} ${DIROWNER} "${dstmanufpath}" ; then
+		gettext "unable to create destination directories" 2>/dev/null
+		return 3
+	fi
+
+	# Copy source PPD file, and compress if needed, to destination
+	if [[ "${ppdfileext}" = "${PEXT}" ]] ; then
+		${GZIP} "${1}" >"${dst_copy_path}" 2>/dev/null
+		if [[ $? -eq 1 ]] ; then
+			gettext "unable to copy PPD file " 2>/dev/null
+			gettext "to destination" 2>/dev/null
+			return 3
+		fi
+	else
+		/bin/cp -f "${1}" "${dst_copy_path}" >/dev/null 2>&1
+		if [[ $? -ne 0 ]] ; then
+			gettext "unable to copy PPD file " 2>/dev/null
+			gettext "to destination" 2>/dev/null
+			return 3
+		fi
+	fi
+	set_perms ${FILEMODE} ${FILEOWNER} "${dst_copy_path}"
+
+	echo "${dst_copy_path}"
+
+	return 0
+}
+
+#
+# Returns 0 if the cache needs to be modified, otherwise
+# returns 1.
+#
+# $1	- Full path to cache
+# $2	- Full path to cache replacement candidate
+#
+changes_in_cache()
+{
+	if debugger "changes_in_cache" ; then
+		set -x
+	fi
+
+	if [[ "${action}" = "${REBUILD}" ]] ; then
+		return 0
+	fi
+	[[ "${2}" -nt "${1}" ]] || return 1
+	if $(${CMP} "${1}" "${2}" >/dev/null 2>&1) ; then
+		# No differences.  Just update timestamp
+		/bin/touch -r "${2}" "${1}" >/dev/null 2>&1
+		return 1
+	else
+		return 0
+	fi
+}
+
+#
+# Generate a new golden cache file (/var/lp/ppd/ppdcache),  by
+# concatenating and sorting all existing cache files in /var/lp/ppd/caches.  
+#
+# If there are difference between the newly generated golden cache file and
+# the existing one (if it exists) then the newly generated one replaces the
+# existing one at /var/lp/ppd/ppdcache.  
+#
+update_golden_cache()
+{
+
+	if debugger "update_golden_cache" ; then
+		set -x
+	fi
+
+	#
+	# Remove any cache files that don't have an associated
+	# label.
+	#
+	for cname in $(/bin/ls ${VARCACHES} 2>/dev/null) ; do
+		repname="${cname%%:*}"
+		cfile="${cname#*:}"
+		checkdir="$(get_rep_path ${repname})/${cfile}"
+		remove_unassociated_cache "${checkdir}" "${cname}"
+	done
+
+	#
+	# Combine the contents of all cache files into a
+	# temporary golden cache file.
+	#
+	tmpgoldencache=$(/bin/mktemp -p "${ppdmgrtmpdir}" \
+	    tmpgoldencache.XXXXXX 2>/dev/null)
+	/bin/sort "${VARCACHES}"/* >>"${tmpgoldencache}" 2>/dev/null
+
+	if [[ ! -s "${tmpgoldencache}" ]] ; then
+		# No cache files. Remove golden cache.
+		/bin/rm -f "${GOLDCACHE}" >/dev/null 2>&1
+		/bin/rm -f "${tmpgoldencache}" >/dev/null 2>&1
+	elif [[ -e "${GOLDCACHE}" ]] ; then
+		#
+		# Use the newly generated "temporary" golden cache file if there
+		# differences between the current and newly generated ppdcache
+		# or if a rebuild is being performed.
+		#
+		if [[ "${VARCACHES}" -nt "${GOLDCACHE}" ]] || \
+		    changes_in_cache "${GOLDCACHE}" "${tmpgoldencache}" ; then
+			set_perms ${FILEMODE} ${FILEOWNER} "${tmpgoldencache}"
+			/bin/mv -f "${tmpgoldencache}" \
+			    "${GOLDCACHE}" >/dev/null 2>&1
+		else
+			/bin/rm -f "${tmpgoldencache}" >/dev/null 2>&1
+		fi
+	else
+		# There wasn't an existing ppdcache.  Install the newly
+		# generated ppdcache file to the golden ppdcache.
+		set_perms ${FILEMODE} ${FILEOWNER} "${tmpgoldencache}"
+		/bin/mv -f "${tmpgoldencache}" "${GOLDCACHE}" >/dev/null 2>&1
+	fi
+}
+
+#
+# Returns a list of PPD files that exist.
+#
+# $1	- Full path to cache file
+#
+remove_invalid_cache_entries()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	[[ -s "${1}" ]] || return
+
+	IFS="$NoSpaceTabIFS"
+	for centry in $(/bin/cat "${1}" 2>/dev/null) ; do
+		IFS="$SaveIFS"
+		#
+		# Keep the entry from the ppd cache if it still
+		# exists and there haven't been any modifications
+		# since the last update to the cache.
+		#
+		if [[ -n "${centry}" ]] ; then
+			ppdfile="${centry##*:}"
+			if [[ -n "${ppdfile}" && -e "${ppdfile}"  &&
+			    "${1}" -nt "${ppdfile}" ]] ; then
+				echo "${centry}"
+			fi
+		fi
+		IFS="$NoSpaceTabIFS"
+	done
+	IFS="$SaveIFS"
+}
+
+#
+# Returns 0 if the path to the PPD is as follows:
+#	<PPD file repository>/<label>/<manufacturer>/<PPD file>
+# otherwise, returns 1
+#
+# $1	 Full path to PPD file
+#
+verify_ppd_location()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	 #
+	 # Strip off what should be <label>/<manufacturer>/<PPD file>
+	 # and verify the PPD file repository matches one of the
+	 # known PPD file repositories.
+	 #
+	ppd_file_repository=${1%/*/*/*}
+	found=1
+	for repository in ${REPOSITORIES} ; do
+		if [[ "${repository}" = "${ppd_file_repository}" ]] ; then
+			found=0
+			break
+		fi
+	done
+	return ${found}
+}
+
+#
+# Generate, and sort, cache entries for each PPD files in the specified
+# list to the specified file.
+#
+# $1	- List of full paths to PPD files
+# $2	- Full path to current cache file
+# $3	- Full path to label
+# $4	- Full path to new cache file to generate
+#
+# Return code:
+#	0 success
+#	1 unsuccessful
+#
+generate_label_cache_file()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	#
+	# Generate a cache file containing cache entries for
+	# all files in the label.
+	#
+	ucfile=$(/bin/mktemp -p "${ppdmgrtmpdir}" \
+	    unsortedcache.XXXXXX 2>/dev/null)
+
+	#
+	# Before processing new files, remove any cache entries
+	# which may be invalid.
+	#
+	valid_files=
+	if [[ -e "${2}" && "${action}" != "${REBUILD}" ]] ; then
+		valid_files=$(remove_invalid_cache_entries "${2}")
+		if [[ -n "${valid_files}" ]] ; then
+			echo "${valid_files}" >>${ucfile}
+		fi
+	fi
+
+	# 
+	# If there are no valid PPD files in the current cache file,
+	# and there are no new PPD files to process, the only thing
+	# left to do is to remove the current cache file.
+	#
+	if [[ -z "${valid_files}" && -z "${1}" ]] ; then
+		/bin/rm -f "${2}" >/dev/null 2>&1
+		/bin/rm -f "${ucfile}" >/dev/null 2>&1	
+		return 0
+	fi
+
+	#
+	# For each of the label's PPD files, generate
+	# a cache file entry and add it to the cache file.
+	#
+	vpl_rc=0
+	vpf_rc=0
+	vpl_msg=
+	vpf_msg=
+	IFS="$NoSpaceTabIFS"
+	for fname in ${1} ; do
+		IFS="$SaveIFS"
+		if [[ -n "${fname}" ]] ; then
+			verify_ppd_location "${fname}"
+			vpl_rc=$?
+			if [[ ${vpl_rc} -ne 0 ]] ; then
+				vpl_msg="${vpl_msg}\t${fname}\n"
+			fi
+				
+			verify_ppd_file "${fname}"
+			vpf_rc=$?
+			if [[ ${vpf_rc} -ne 0 ]] ; then
+				vpf_msg="${vpf_msg}\t${fname}\n"
+			fi
+
+			if [[ ${vpl_rc} -eq 0 && ${vpf_rc} -eq 0 ]] ; then
+				echo "$(generate_cache_file_entry \
+				    "${modmanuf}" "${model}" "${nickn}" \
+				    "${devidmfg}" "${devidmdl}" "${fname}")"
+			fi
+		fi
+		IFS="$NoSpaceTabIFS"
+	done >>"${ucfile}" 
+	IFS="$SaveIFS"
+	/bin/sort -u "${ucfile}" >>"${4}" 2>/dev/null
+	/bin/rm -f "${ucfile}" >/dev/null 2>&1
+
+	[[ -n "${vpl_msg}" || -n "${vpf_msg}" ]] || return 0
+	if [[ -n ${vpl_msg} ]] ; then
+		gettext "  PPD file(s) not in valid location\n" 2>/dev/null
+		gettext \
+	    "  (<repository>/<label>/<manufacturer>/<PPD file>):\n" 2>/dev/null
+		echo "${vpl_msg}"
+	fi
+	if [[ -n ${vpf_msg} ]] ; then
+		gettext "  invalid PPD file(s):\n" 2>/dev/null
+		echo "${vpf_msg}"
+	fi
+	return 1
+}
+
+#
+# Update current cache file with candidate cache file if there are
+# differences.
+#
+# $1	- Current cache file
+# $2	- Candidate cache file to update
+# $3	- Repository name
+#
+update_current_cache_file()
+{
+	if debugger "update_current_cache_file" ; then
+		set -x
+	fi
+
+	if [[ ! -s "${2}" ]] ; then
+		#
+		# Candidate cache has zero size (label
+		# directory with no PPD files under it).
+		# Delete the empty candidate cache
+		# file and delete the current cache
+		# file.
+		#
+		/bin/rm -f "${1}" >/dev/null 2>&1
+		/bin/rm -f "${2}" >/dev/null 2>&1
+	elif [[ -e "${1}" ]] ; then
+		#
+		# If there are differences between the current
+		# cache file and the newly generated one, then
+		# replace the current one with the new one, and
+		# set the flag to update the golden ppdcache
+		# file.
+		#
+		if changes_in_cache "${1}" "${2}" ; then
+			set_perms ${FILEMODE} ${FILEOWNER} "${2}"
+			/bin/mv -f "${2}" "${1}" >/dev/null 2>&1
+		else
+			/bin/rm -f "${2}" >/dev/null 2>&1
+		fi
+	else
+
+		#
+		# There is no current cache file.  Move the candidate
+		# to the caches directory.
+		#
+		set_perms ${FILEMODE} ${FILEOWNER} "${2}"
+		/bin/mv -f "${2}" "${1}" >/dev/null 2>&1
+	fi
+}
+
+#
+# Returns 0 if there are files in $1 with newer timestamp
+# than $2 or if deletions have occurred under $1,
+# otherwise returns 1.
+#
+# $1	- Full path to the destination label
+# $2	- Full path to label cache file
+#
+changes_under_label()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	# First check for newer files in the directory
+	if [[ -e "${2}" && "${action}" != "${REBUILD}" ]] ; then
+		newfiles=$(/bin/find "${1}" -type f -newer "${2}")
+	else
+		newfiles=$(/bin/find "${1}" -type f)
+	fi
+	echo "${newfiles}"
+	[[ -z "${newfiles}" ]] || return 0
+
+	#
+	# Need to detect if PPD files have been deleted by checking
+	# timestamps on label and manufacturer directories.
+	#
+	[[ ! "${1}" -nt "${2}" ]] || return 0
+	/bin/find "${1}" -type d -newer "${2}" >/dev/null 2>&1 || return 1
+	return 0
+}
+
+#
+# If -R was specified, or the timestamp on the specified label's
+# directory or any of the PPD files under the specified label in
+# the specified PPD file respository is newer than the cache file
+# associated with the label, then generate a new sorted cache file.
+#
+# The new cache will replace the existing one (if any) only if there
+# are differences.  Note: if -r was specified, then a new cache file
+# file will always be installed at
+#	/var/lp/ppd/caches/<PPD file repository name>-<label name>
+#
+# $1	- Full path of the destination PPD file repository
+# $2	- Destination PPD file repository name
+# $3	- Destination label name
+#
+update_label_cache()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	dstlabelpath="${1}/${3}"
+	replabelcachepath="${1}/${CACHES}/${3}"
+	varlabelcachepath="${VARCACHES}/${2}${SEP}${3}"
+
+	ulc_rc=0
+	if [[ -d "${dstlabelpath}" ]] ; then
+
+		#
+		# If the cache doesn't exist for a label,
+		# or if there were any changes under a label
+		# (i.e., the timestamp on the label directory or any
+		# of the PPD files under it is newer than the
+		# existing cache file), then generate a new cache file.
+		#
+		tmpcachepath=$(/bin/mktemp -p "${ppdmgrtmpdir}" \
+		    tmpcachepath.XXXXXX 2>/dev/null)
+		newfileslist=$(changes_under_label "${dstlabelpath}" \
+		    "${varlabelcachepath}")
+		if [[ $? -eq 0 ]] ; then
+			err_files=$(generate_label_cache_file \
+			    "${newfileslist}" "${varlabelcachepath}" \
+			    "${dstlabelpath}" "${tmpcachepath}")
+			if [[ $? -ne 0 ]] ; then
+				#
+				# At least one PPD file was invalid.
+				# Don't return yet, as the cache info
+				# for the valid PPD files can still be
+				# used to generate a cache file.
+				#
+				echo "${err_files}"
+				ulc_rc=1
+			fi
+		fi
+
+		if [[ -e "${tmpcachepath}" ]] ; then
+			update_current_cache_file \
+			    "${varlabelcachepath}" "${tmpcachepath}" "${2}"
+			/bin/rm -f "${tmpcachepath}" >/dev/null 2>&1
+		fi
+	else
+		#
+		# If there is a cache file in /var/lp/ppd/caches associated
+		# with the label which no longer exists, remove it.
+		#
+		/bin/rm -f "${varlabelcachepath}" >/dev/null 2>&1
+	fi
+	return ${ulc_rc}
+}
+
+#
+# Returns the alias for the specified real manufacturer's name.
+#
+# $1	- Real manufacturer's name
+# $2	- File containing list of files that have manufacturers aliases
+#
+manuf_name_alias()
+{
+	if debugger ; then
+		set -x
+	fi
+	
+	#
+	# Found a couple of PPD files which had special characters
+	# in the Manufacturer name (i.e, the following is the Manufacturer
+	# entry:
+	#	*Manufacturer:  "Canon Inc. (Kosugi Offic"
+	# We'll only search the alias file for "Canon Inc."
+	#
+	tmpmanuf="${1% *\(*}"
+
+	# Search alias files for a match on the real manufacturer name
+	if [[ -s "${2}" ]] ; then
+		#
+		# Check the manufacturer aliases file for case
+		# insensitive match of the Manufacturer entry
+		# from the PPD file.  If a match is found,
+		# then modify the manufacturer entry to
+		# be that of the specified alias.
+		#
+		manufaliases=$(/bin/egrep -i \
+		    "^${tmpmanuf}:|:${tmpmanuf}:|:${tmpmanuf}$" "${2}")
+		if [[ -n "${manufaliases}" ]] ; then
+			echo "${manufaliases%%:*}"
+			break
+		else
+			echo "${tmpmanuf}"
+		fi
+	else
+		echo "${tmpmanuf}"
+	fi
+}
+
+#
+# Returns 0 if the extension to the specified PPD file is a known
+# extension, otherwise returns 1.
+#
+# $1	- Full path to PPD file
+#
+# Set upon return:
+#	ppdfileext	- PPD file ext (.ppd or .ppd.gz)
+#
+verify_file_ext()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	if [[ "${1%.gz}".gz = "${1}" ]] ; then
+		ppdfileext=${GEXT}
+	elif [[ "${1%.ppd}".ppd = "${1}" ]] ; then
+		ppdfileext=${PEXT}
+	else
+		# invalid PPD file name extension
+		return 1
+	fi
+
+	return 0
+}
+
+#
+# Return the lines from the specified PPD file matching the specified
+# spec items.
+#
+# $1	- spec entries from PPD file
+# $2	- spec item
+#
+# $1 example - 1 string with substrings separated by newline:
+#	*PPD-Adobe: "4.3"
+#	*Manufacturer: "HP"
+#	*Product:       "(officejet 4200 series)"
+#	*ModelName:     "HP OfficeJet 4200"
+#	*NickName:      "HP OfficeJet 4200 Foomatic/hpijs (recommended)"
+# $2 example:
+#	^\*Manufacturer
+#
+spec_entry()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	item=$(echo "${1}" | /bin/grep ${2})
+	# Remove everything up to and including the first quote
+	item=${item#*\"}
+	# Remove the end quote
+	echo "${item%\"}"
+}
+
+#
+# Return the lines from the specified PPD file matching the specified
+# spec items.
+#
+# Note: this is similar to spec_entry() except the tokens in the
+# spec entry are different.  
+#
+# $1	- spec entries from PPD file
+# $2	- spec item
+#
+devid_spec_entry()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	item=$(echo "${1}" | /bin/grep ${2})
+	# Remove everything up to and including the first semi-colon
+	item=${item#*\:}
+	# Remove the end quote
+	echo ${item%\;}
+
+}
+
+#
+# Verifies that the specified PPD file
+#	- has a valid extension
+#	- has the following required spec file entries:
+#		*PPD-Adobe: "4.3"
+#		Manufacturer
+#		Product
+#		ModelName
+#		NickName
+#
+# In addition, the manufacture and model from the IEEE1284 device id
+# information will be gathered here, although it's not an error that
+# it isn't in the PPD file as many don't contain the IEEE1284 info.
+#
+# $1	- Full path to PPD file
+#
+# Return codes:
+#	0	success
+#	1	invalid PPD file
+#
+verify_ppd_file()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	ADOBESPEC="PPD-Adobe"
+	MANUF="Manufacturer"
+	PRODUCT="Product"
+	MODEL="ModelName"
+	NICKNAME="NickName"
+	DEVID="1284DeviceID"
+
+	# Verify the PPD file extension
+	verify_file_ext "${1}" || return 1
+
+	# Query for the required spec items
+	searchentries="^\*${ADOBESPEC}:|^\*${MANUF}:|^\*${PRODUCT}:"
+	searchentries="${searchentries}|^\*${MODEL}:|^\*${NICKNAME}:"
+	searchentries="${searchentries}|^\*${DEVID}:"
+	ppd_info="$(/bin/gzgrep -e "${searchentries}" "${1}")"
+
+	#
+	# Process the query results to verify each of the required spec
+	# file items appears in the PPD file.
+	#
+	for spec_item in ${ADOBESPEC} ${MANUF} ${PRODUCT} ${MODEL} \
+	    ${NICKNAME} ; do
+		entry=$(spec_entry "${ppd_info}" "^\*${spec_item}:")
+		[[ ! -z "${entry}" ]] || return 1
+		case ${spec_item} in
+		${MANUF})
+			realmanuf="${entry}"
+			;;
+		${PRODUCT})
+			product="${entry}"
+			;;
+		${MODEL})
+			model="${entry}"
+			;;
+		${NICKNAME})
+			#
+			# Remove the model and any commas and spaces
+			# which appear before the driver
+			#
+			nickn="${entry#$model[, ]*}"
+			;;
+		esac
+			
+	done
+
+	# Save IEEE1284 device id information
+	if $(echo "${ppd_info}" | grep "${DEVID}" >/dev/null 2>&1) ; then
+		DMDL="MDL"
+		DMFG="MFG"
+		devid="$(/bin/gzgrep -e "^[ ]*${DMDL}:|^[ ]*${DMFG}:" "${1}")"
+		devidmdl="$(devid_spec_entry "${devid}" "${DMDL}")"
+		devidmfg="$(devid_spec_entry "${devid}" "${DMFG}")"
+	else
+		devidmdl=
+		devidmfg=
+	fi
+	modmanuf=$(manuf_name_alias "${realmanuf}" ${aliasfile})
+
+	return 0
+}
+
+#
+# generate_cache_file_entry()
+#
+# Returns a cache file entry for the specified PPD file.
+#
+# $1	- modmanuf
+# $2	- model
+# $3	- nickn
+# $4	- devidmfg
+# $5	- devidmdl
+# $6	- Full path to the specified PPD file
+#
+generate_cache_file_entry()
+{
+	if debugger "generate_cache_file_entry" ; then
+		set -x
+	fi
+
+	echo "${1}":"${2}":"${3}":"${4}":"${5}":"${6}"
+}
+
+#
+# Expand specified file to the full path.
+#
+# $1	- File path to expand
+#
+# Return code set to 0 if expanded successfully, otherwise set to 1.
+#
+ppd_pathname()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	if [[ -f "${1}" && -s "${1}" ]] ; then
+		(cd "$(/bin/dirname "${1}")" ; \
+		    echo "$(/bin/pwd)/$(/bin/basename "${1}")") || return 1
+		return 0
+	else
+		return 1
+	fi
+}
+
+#
+# Returns the PPD repsitory path associated with the specified
+# PPD repository name.
+#
+# $1	- Repository name
+#
+get_rep_path()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	case ${1} in
+	${SYSTEM})
+		echo "${SYSTEMREP}"
+		;;
+	${VENDOR})
+		echo "${VENDORREP}"
+		;;
+	${ADMIN})
+		echo "${ADMINREP}"
+		;;
+	${USER})
+		echo "${USERREP}"
+		;;
+	*)
+		echo "${UNSET}"
+		;;
+	esac
+}
+
+#
+# Returns the PPD respository name from the repository path
+#
+# $1	- PPD repository path
+#
+get_rep_name()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	case ${1} in
+	${SYSTEMREP})
+		echo "${SYSTEM}"
+		;;
+	${VENDORREP})
+		echo "${VENDOR}"
+		;;
+	${ADMINREP})
+		echo "${ADMIN}"
+		;;
+	${USERREP})
+		echo "${USER}"
+		;;
+	"all")
+		echo "all"
+		;;
+	*)
+		echo "${UNSET}"
+		;;
+	esac
+}
+
+#
+# Returns 0 if a matching label name is found in the specified repository,
+# otherwise returns 1.
+# 
+# $1	- repository path
+# $2	- label name
+#
+label_path_in_repository()
+{
+	if debugger "label_path_in_repository" ; then
+		set -x
+	fi
+
+	[[ "${1}" != "" && "${2}" != "" ]] || return 1
+	lpir_rc=1
+	for repository in ${REPOSITORIES} ; do
+		if [[ "${repository}" = "${1}" && -d "${1}/${2}" ]] ; then
+			lpir_rc=0
+			break
+		fi
+	done
+	return ${lpir_rc}
+}
+
+#
+# Returns 0 if the source label path is the same
+# as the destination label path, otherwise returns 1.
+#
+# $1	- full path to source PPD file (source label path)
+# $2	- destination repository path
+# $3	- destination label name
+#
+label_path_match()
+{
+	if debugger "label_path_match" ; then
+		set -x
+	fi
+
+	# dest repository not specified
+	if [[ "${2}" = "${UNSET}" ]] ; then
+		# dest label not specified
+		if [[ "${3}" = "${UNSET}" ]] ; then
+			#
+			# We've found a match if the label path is in a known
+			# repository.
+			#
+			lpath="${1%/*/*}"
+			label_path_in_repository \
+			    "${1%/*/*/*}" "${lpath##*/}" || return 1
+		else
+			# 
+			# If the source label path exists in the
+			# in a known repository, and the destination
+			# label is the same as the source label,
+			# then we'll assume the default destination
+			# repository is the same as the source
+			# destination repository.
+			# 
+			[[ "${1%/*/*}" = "${1%/*/*/*}/${3}" ]] || return 1
+			label_path_in_repository "${1%/*/*/*}" "${3}" || \
+			    return 1
+		fi
+
+	# dest repository specified, dest label not specified
+	elif [[ "${3}" = "${UNSET}" ]] ; then
+		#
+		# If the destination repository path is the same as the
+		# source repository, and if the source label exists in the
+		# destination repository path, then we'll assume the default
+		# destination label is the same as the source label.
+		#
+		[[ "${2}" = "${1%/*/*/*}" ]] || return 1
+		lpath="${1%/*/*}"
+		label_path_in_repository "${2}" "${lpath##*/}" || return 1
+
+	# dest repository and dest label specified.
+	else
+		#
+		# We've found a match if the destination and label
+		# match those of the source label path, and the source
+		# label path is in a known repository.
+		#
+		[[ "${1%/*/*}" = "${2}/${3}" ]] || return 1
+		label_path_in_repository "${2}" "${3}" || return 1
+	fi
+	return 0
+}
+
+#
+# Returns 0 if specified label name is a reserved label, otherwise
+# returns 1.
+#
+# $1	- label name
+#
+reserved_label()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	rl_rc=1
+	for labelname in ${RESERVEDLABELS} ; do
+		if [[ "${1}" = "${labelname}" ]] ; then
+			rl_rc=0
+			break
+		fi
+	done
+	return ${rl_rc}
+}
+
+#
+# Returns a list of all labels that exist in a repository that are
+# not reserved labels.
+#
+# $1	- Full path of repository
+# $2	- Repository name
+#
+get_rep_label_list()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	#
+	# Get a list of all labels that exist in all of the
+	# PPD file repository.
+	#
+	for lname in $(/bin/ls "${1}" 2>/dev/null) ; do
+		if [[ -d "${1}/${lname}" ]] ; then
+			if ! reserved_label "${lname}" ; then
+				echo "${lname} "
+			fi
+		fi
+	done
+}
+
+#
+# Returns a valid PPD label.
+#
+# Verifies the specified PPD label is a valid label.  If the
+# label is not set, then it is set to a default value.
+#
+# Return code set to 0 if the specified PPD label is valid, otherwise 1.
+#
+# $1	- PPD label
+#
+valid_specified_label()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	# Verify the specified label
+	vsl_rc=0
+	case "${1}" in
+	"all")
+		# Reserved label name with -a or -g options
+		if [[ "${action}" = "${ADD}" || \
+		    "${action}" = "${GENERATEENTRY}" ]] ; then
+			print -n "$myprog: " 1>&2
+			gettext "reserved PPD label name: ${1}\n" 1>&2
+			vsl_rc=1
+		else
+			echo "${1}"
+		fi
+		;;
+
+	"ppdcache" | "caches" | "manufaliases")
+		# Reserved label names with any option
+		print -n "$myprog: " 1>&2
+		gettext "reserved PPD label name: ${1}\n" 1>&2
+		vsl_rc=1
+		;;
+
+	"" | "${UNSET}")	
+		# Label name not specified.  Set the default label name.
+		# For -g and -a, default is "user", otherwise, default
+		# is "all".
+		if [[ "${action}" = "${ADD}" || \
+		    "${action}" = "${GENERATEENTRY}" ]] ; then
+			echo "${USER}"
+		else
+			echo "all"
+		fi
+		;;
+
+	*)
+		# label cannot be "." or ".."
+		if [[ "${1}" = "." || "${1}" = ".." ]] ; then
+			print -n "$myprog: " 1>&2
+			gettext "PPD label name cannot be " 1>&2
+			gettext "\".\" or \"..\"\n" 1>&2
+			vsl_rc=1
+		fi
+
+		# Label name cannot contain special characters
+		echo "${1}" | /bin/egrep "${SPECIALCHARS}" >/dev/null
+		if [[ $? -eq 0 ]] ; then
+			print -n "$myprog: " 1>&2
+			gettext "PPD label name contains " 1>&2
+			gettext "an invalid character: ${1}\n" 1>&2
+			vsl_rc=1
+		else
+			echo "${1}"
+		fi
+		;;
+	esac
+	return ${vsl_rc}
+}
+
+#
+# Returns the full path of any variant copy of the source file in
+# the destination label/repository.  
+# 
+# $1	- Full path to source PPD file
+# $2	- Full path to destination PPD file
+#
+# Return code set to
+#	0	- Copy doesn't exist
+#	1	- Duplicate copy exists
+#	2	- Variant copy exists
+#
+variant_copy()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	#
+	# First make sure there is not a .ppd and a .ppd.gz version
+	# of the destination file; users should know not to do this.
+	#
+	if [[ -e "${2%.gz}" && -e "${2%.gz}.gz" ]] ; then
+		/bin/rm -f "${2%.gz}" >/dev/null 2>&1
+	fi
+
+	# Use gzcmp to compare PPD files as it can deal with
+	# gzipped or regular files.
+	if $(${GZCMP} "${1}" "${2}"* >/dev/null 2>&1) ; then
+		echo "${2}"*
+		return 1
+	elif [[ -e "${2%.gz}" ]] ; then
+		echo "${2%.gz}"
+		return 2
+	elif [[ -e "${2%.gz}.gz" ]] ; then
+		echo "${2%.gz}.gz"
+		return 2
+	else
+		#
+		# A PPD file doesn't exist in the destination
+		# repository under the destination label.
+		# Just display the source PPD file, ensuring
+		# it has a gzip extension as we will always
+		# try to gzip the copy in the destination.
+		#
+		if [[ "${1#*.ppd}" = ".gz" ]] ; then
+			echo "${2}"
+		else
+			echo "${2}.gz"
+		fi
+		return 0
+	fi
+}
+
+#
+# $1	- Directory mode
+# $2	- Directory owner (i.e., root:lp)
+# $3	- Directory to create
+#
+make_dir() 
+{
+	if debugger "make_dir" ; then
+		set -x
+	fi
+
+	[[ ! -d "${3}" ]] || return 0
+	/bin/mkdir "${3}" >/dev/null 2>&1 || return 1
+	set_perms ${1} ${2} "${3}"
+	return 0
+}
+
+#
+# Remove a ppdmgr generated cache (in /var/lp/ppd/cache)
+# if it doesn't have an associated label in the repository.
+# 
+# $1	- Full path to label
+# $2	- Cache name
+#
+remove_unassociated_cache()
+{
+	if debugger "remove_unassociated_cache" ; then
+		set -x
+	fi
+
+	if [[ "${1}" != "${UNSET}" ]] ; then
+		if [[ -n "${1}" && ! -d "${1}" ]] ; then
+			#
+			# The label doesn't exist, so delete
+			# the associated cache file.
+			#
+			/bin/rm -f "${VARCACHES}/${2}" >/dev/null 2>&1
+		fi
+	fi
+}
+
+#
+# Sorted copies of cache files for each label in each PPD repository
+# are maintained in /var/lp/ppd/caches/<PPD respository>-<label>.
+# This is done so that changes in delivered cache files can be
+# detected.  If a difference in cache files is detected, or a
+# cache file is either added or removed, then we know that
+# the ppdcache file needs to be updated.
+#
+# Get a list of all cache files and compare against the list
+# of labels in all of the PPD file repositories.  They should
+# be the same.  If there is a label in one of the PPD file
+# repositories that doesn't have an associated cache file, then
+# we don't worry about it now, as that will be resolved when
+# we update the cache for that label.  However, if there is
+# a cache file associated with a label that no longer exists, then
+# remove the cache file.
+#
+# $1	- Full path to repository (or "all")
+# $2	- Label name
+#
+update_cache()
+{
+	if debugger ; then
+		set -x
+	fi
+
+	#
+	# Determine which labels in which PPD repository the
+	# cache file will be updated for.
+	#
+	if [[ "${1}" = "all" ]] ; then
+		rname="${REPOSITORIES}"
+	else
+		rname="${1}"
+	fi
+
+	uc_rc=0
+	for dstreppath in ${rname} ; do
+		labellist=
+		if [[ "${2}" = "all" ]] ; then
+			dstrepname=$(get_rep_name "${dstreppath}")
+			labellist=$(get_rep_label_list "${dstreppath}" \
+			    "${dstrepname}")
+		else
+
+			# Ensure the label exists in the PPD file repository.
+			if [[ -d "${dstreppath}/${2}" ]] ; then
+				labellist="${2}"
+			fi
+		fi
+
+		#
+		# Update the cache for each label in the PPD repository
+		#
+		for dstlabel in ${labellist} ; do
+			ulc_msg=$(update_label_cache "${dstreppath}" \
+			    "${dstrepname}" "${dstlabel}")
+			if [[ $? -ne 0 ]] ; then
+				echo "${ulc_msg}"
+				uc_rc=1
+			fi
+		done
+	done
+
+	# Update the golden cache file.
+	update_golden_cache
+	return ${uc_rc}
+}
+
+# $1	- exit status
+ppdmgr_exit()
+{
+	if debugger "ppdmgr_exit" ; then
+		set -x
+	fi
+
+	/bin/rm -rf "${ppdmgrtmpdir}" >/dev/null 2>&1
+	exit ${1}
+}
+
+
+usage()
+{
+	gettext "usage:\n" 1>&2
+	print -n "\t$myprog: " 1>&2
+	gettext "-a <ppd_filename_path> [ -L <label> ]\n" 1>&2
+	gettext "\t\t[ -R <ppd_repository> ] [-w]\n" 1>&2
+	print -n "\t$myprog: " 1>&2
+	# gettext "-g <ppd_filename_path> [ -L <label> ]\n" 1>&2
+	# gettext "\t\t[ -R <ppd_repository> ]\n" 1>&2
+	print -n "\t$myprog: " 1>&2
+	gettext "-r [ -L <label> ] [ -R <ppd_repository> ]\n" 1>&2
+	print -n "\t$myprog: " 1>&2
+	gettext "-u [ -L <label> ] [ -R <ppd_repository> ]\n" 1>&2
+
+	ppdmgr_exit ${FAIL}
+}
+
+##########################################################################
+# main
+##########################################################################
+
+myprog=$(/bin/basename $0)
+
+SaveIFS="$IFS"
+NoSpaceTabIFS='
+'
+
+# Updatable PPD repository
+VARDIR=/var/lp/ppd
+
+# Delivered PPD respository
+SYSTEMREP=/usr/share/ppd
+ADMINREP=/usr/local/share/ppd
+VENDORREP=/opt/share/ppd
+USERREP=${VARDIR}
+
+RESERVEDREPS="${SYSTEMREP} ${ADMINREP} ${VENDORREP}"
+REPOSITORIES="${USERREP} ${RESERVEDREPS}"
+RESERVEDLABELS="all caches ppdcache manufaliases"
+
+# Deliveries
+SYSTEM=system
+VENDOR=vendor
+ADMIN=admin
+USER=user
+
+# Sytem PPD cache name used by printmgr
+GOLDCACHE=${USERREP}/ppdcache
+
+# Delivered caches directory
+CACHES=caches
+MANUFALIASES=manufaliases
+
+# Updated caches directory
+VARCACHES=${VARDIR}/${CACHES}
+
+# valid PPD file name extensions
+PEXT=ppd
+GEXT=gz
+FILEEXTS=".${PEXT} .${PEXT}.${GEXT}"
+
+# Default modes and owners
+DIRMODE=755
+DIROWNER=root:lp
+ADMINOWNER=root:root
+FILEMODE=444
+FILEOWNER=root:lp
+
+# ppdmgr actions
+ADD=add
+GENERATEENTRY=generateentry
+UPDATE=update
+REBUILD=rebuild
+
+SUCCESS=0
+FAIL=1
+WARN=2
+
+MAXLABELNAME=256
+GZIP="/bin/gzip -c"
+GZCMP="/bin/gzcmp -s"
+CMP="/bin/cmp -s"
+SPECIALCHARS=":"
+SEP=":"
+
+debug=0
+wflag=0
+status=${SUCCESS}
+
+UNSET=""
+ppdlabel=${UNSET}
+ppdrepname=${UNSET}
+ppdreppath=${UNSET}
+modmanuf=
+model=
+nickn=
+devidmdl=
+devidmfg=
+
+ppdmgrtmpdir=/tmp/ppdmgr.$$
+/bin/mkdir "${ppdmgrtmpdir}" >/dev/null 2>&1
+set_perms ${DIRMODE} ${DIROWNER} "${ppdmgrtmpdir}"
+
+aliasfile=${USERREP}/manufaliases
+tmpfilepath=
+
+
+OPTS=a:g:L:rR:uwZ
+while getopts "$OPTS" arg ; do
+	case ${arg} in
+	a)	# add PPD file
+		action=${ADD}
+		origsrcppdpath=${OPTARG}
+		;;
+
+	g)	# create cache entry
+		action=${GENERATEENTRY}
+		origsrcppdpath=${OPTARG}
+		;;
+
+	L)	# PPD label name
+		ppdlabel=${OPTARG}
+		;;
+
+	r)	# rebuild cache
+		action=${REBUILD}
+		;;
+
+	R)	# PPD file repository to use
+		ppdrepname=${OPTARG}
+		;;
+
+	u)	# update cache
+		action=${UPDATE}
+		;;
+
+	w)	# display PPD file path
+		wflag=1
+		;;
+
+	Z)	# debug
+		debug=1
+		;;
+
+	?)
+		usage
+		;;
+	esac
+done
+
+if debugger "Main" ; then
+	set -x
+fi
+
+if [[ $# -lt 1 || -z "${action}" ]] ; then
+	usage
+fi
+
+# ignore wflag unless specified with -a
+if [[ ${wflag} -eq 1 && "${action}" != ${ADD} ]] ; then
+	wflag=0
+fi
+
+#
+# Ensure the destination PPD repository directory is set
+# to match the specified repository.  If the
+# destination PPD file repository was specified, then
+# it must be one of the following:
+# 	"user"
+#	"admin"
+#	"vendor"
+#	"system"
+#	"all"
+#
+case "${ppdrepname}" in
+"${SYSTEM}")
+	ppdreppath="${SYSTEMREP}"
+	;;
+"${ADMIN}")
+	ppdreppath="${ADMINREP}"
+	;;
+"${VENDOR}")
+	ppdreppath="${VENDORREP}"
+	;;
+"${USER}")
+	ppdreppath="${USERREP}"
+	;;
+"all")
+	if [[ "${action}" = "${ADD}" || \
+	    "${action}" = "${GENERATEENTRY}" ]] ; then
+		print -n "$myprog: " 1>&2
+		gettext "reserved PPD repository name: " 1>&2
+		gettext "${ppdrepname}\n" 1>&2
+		ppdmgr_exit ${FAIL}
+	fi
+	ppdreppath="all"
+	;;
+"${UNSET}"|"")
+	ppdreppath="${UNSET}"
+	;;
+
+*)
+	print -n "$myprog: " 1>&2
+	gettext "invalid PPD repository name: ${ppdrepname}\n" 1>&2
+	ppdmgr_exit ${FAIL}
+	;;
+esac
+
+#
+# When a source PPD file's path is from a known repository, the
+# destination repository and desination label are assumed to be the
+# same as the source PPD file's unless a differing repository or label
+# was specified.
+#
+if [[ "${action}" = "${ADD}" || "${action}" = "${GENERATEENTRY}" ]] ; then
+
+	srcppdpath=$(ppd_pathname "${origsrcppdpath}")
+	ppd_pathname_rc=$?
+	if [[ ${ppd_pathname_rc} -ne 0 ]] ; then
+		print -n "$myprog: " 1>&2
+		gettext "invalid PPD file: ${origsrcppdpath}\n" 1>&2
+		ppdmgr_exit ${ppd_pathname_rc}
+	fi
+
+	# Path cannot contain special characters
+	echo "${srcppdpath}" | /bin/egrep  "${SPECIALCHARS}" >/dev/null
+	if [[ $? -eq 0 ]] ; then
+		print -n "$myprog: " 1>&2
+		gettext "PPD path contains " 1>&2
+		gettext "an invalid character: ${ppd_pathname}\n" 1>&2
+		ppdmgr_exit ${FAIL}
+	fi
+	ppdfname=$(/bin/basename "${origsrcppdpath}")
+
+	#
+	# Check to see if there's any work to be done.  If the source file
+	# is already in the destination repository under the destination
+	# label, then there's nothing left to do.  We exit rather than
+	# going on to do an update on the label in the repository as
+	# it could possible take a long time to update.  If an add was
+	# requested, it could have come from an application, so we want
+	# to return quickly.
+	#
+	if label_path_match "${srcppdpath}" "${ppdreppath}" "${ppdlabel}" ; then
+		if [[ ${wflag} -eq 1 || \
+		    "${action}" = "${GENERATEENTRY}" ]] ; then
+			echo "${srcppdpath}"
+		fi
+		ppdmgr_exit ${SUCCESS}
+	fi
+fi
+
+ppdlabel=$(valid_specified_label "${ppdlabel}")
+if [[ $? -ne 0 ]] ; then
+	ppdmgr_exit ${FAIL}
+fi
+
+if [[ "${ppdreppath}" = "${UNSET}" ]] ; then
+	ppdreppath="${USERREP}"
+fi
+
+dstrepname=$(get_rep_name "${ppdreppath}")
+
+case "${action}" in
+"${ADD}")
+	#
+	# Attempt to add the PPD file to the repository under the
+	# specified label.  If any errors occur, final_dst_ppd_path
+	# will contain the error message rather than the path to the
+	# PPD file.
+	#
+	final_dst_ppd_path=$(add_ppd "${srcppdpath}" "${ppdfname}" \
+	    "${ppdreppath}" "${dstrepname}" "${ppdlabel}")
+	add_ppd_rc=$?
+	case ${add_ppd_rc} in
+	0)	#
+		# The PPD file was added.  Update the specified
+		# cache associated with the label if the PPD file
+		# was added successfully and was not a duplicate.
+		# Ensure any changes are also reflected in the
+		# golden cache.
+		#
+		add_ppd_msg=$(update_label_cache "${ppdreppath}" \
+		    "${dstrepname}" "${ppdlabel}")
+		apm_rc=$?
+
+		echo "${add_ppd_msg}" | /bin/grep "${final_dst_ppd_path}"
+		path_in_msg=$?
+
+		#
+		# Only report cache update errors if the file that was
+		# added was one that was reported as not being added
+		# to the cache.  This really should happen as the file
+		# was verified during the add.
+		#
+		if [[ ${apm_rc} -ne 0 && ${path_in_msg} -eq 0 ]] ; then
+			print -n "$myprog: " 1>&2
+			gettext "printer information does not reflect " 1>&2
+			gettext "the\nfollowing PPD file(s):\n" 1>&2
+			print "${add_ppd_msg}" 1>&2
+			status=${FAIL}
+		else
+			update_golden_cache
+
+			#
+			# Display the full path to the added PPD file,
+			# if requested (-w).
+			#
+			if [[ ${wflag} -eq 1 ]] ; then
+				print "${final_dst_ppd_path}"
+			fi
+		fi
+		;;
+
+	1)	# Duplicate copy exists
+		if [[ ${wflag} -eq 1 ]] ; then
+			print "${final_dst_ppd_path}"
+		fi
+		;;
+
+	2)	# Varying copy exists
+		print -n "$myprog: " 1>&2
+		gettext "differing variant of source PPD file " 1>&2
+		gettext "already exists at\n" 1>&2
+		gettext "${final_dst_ppd_path}\n" 1>&2
+		status=${FAIL}
+		;;
+	*)	# The PPD file was not added as a problem occurred.
+		# Display the error message.
+		print -n "$myprog: " 1>&2
+		print "${final_dst_ppd_path}" 1>&2
+		status=${FAIL}
+		;;
+
+	esac
+	;;
+
+"${GENERATEENTRY}")
+	#
+	# Create a cache file entry for the specified PPD file and
+	# display it on standard out.
+	#
+	verify_ppd_file "${srcppdpath}"
+	if [[ $? -eq 0 ]] ; then
+		dstdir="${ppdreppath}/${ppdlabel}/${modmanuf}"
+		final_dst_path="${dstdir}/$(/bin/basename ${srcppdpath})"
+		verify_ppd_location "${final_dst_path}"
+		if [[ $? -eq 0 ]] ; then
+			# Generate the cache file entry
+			print "$(generate_cache_file_entry "${modmanuf}" \
+			    "${model}" "${nickn}" "${devidmfg}" "${devidmdl}" \
+			    "${final_dst_path}")"
+		else
+			print -n "$myprog: " 1>&2
+			gettext "PPD file not in valid location\n" 1>&2
+			gettext \
+	    "(<repository>/<label>/<manufacturer>/<PPD file>):\n\t${1}\n" 1>&2
+			status=${FAIL}
+		fi
+
+	else
+		print -n "$myprog: " 1>&2
+		gettext "invalid PPD file: ${1}\n" 1>&2
+		status=${FAIL}
+	fi
+	;;
+	
+"${REBUILD}" | "${UPDATE}")
+	update_msg=$(update_cache "${ppdreppath}" "${ppdlabel}")
+	if [[ $? -ne 0 ]] ; then
+		print -n "$myprog: " 1>&2
+		gettext "printer information does not reflect " 1>&2
+		gettext "the\nfollowing PPD file(s):\n" 1>&2
+		print "${update_msg}" 1>&2
+		status=${WARN}
+	fi
+	;;
+
+*)
+	usage
+	;;
+esac
+
+ppdmgr_exit ${status}
--- a/usr/src/cmd/svc/profile/generic_limited_net.xml	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/svc/profile/generic_limited_net.xml	Thu Mar 08 17:32:28 2007 -0800
@@ -20,7 +20,7 @@
    
     CDDL HEADER END
    
-    Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+    Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     Use is subject to license terms.
 
     ident	"%Z%%M%	%I%	%E% SMI"
@@ -136,9 +136,6 @@
   <service name='system/power' version='1' type='service'>
     <instance name='default' enabled='true'/>
   </service>
-  <service name='application/print/cleanup' version='1' type='service'>
-    <instance name='default' enabled='true' />
-  </service>
   <service name='network/pfil' version='1' type='service'>
     <instance name='default' enabled='true' />
   </service>
@@ -177,10 +174,13 @@
   <service name='application/management/wbem' version='1' type='service'>
     <instance name='default' enabled='true' />
   </service>
-  <service name='application/print/rfc1179' version='1' type='service'>
+  <service name='application/print/ipp-listener' version='1' type='service'>
+    <instance name='default' enabled='false' />
+  </service>
+  <service name='application/print/ppd-cache-update' version='1' type='service'>
     <instance name='default' enabled='true' />
   </service>
-  <service name='application/print/ipp-listener' version='1' type='service'>
+  <service name='application/print/rfc1179' version='1' type='service'>
     <instance name='default' enabled='false' />
   </service>
 
--- a/usr/src/cmd/svc/profile/generic_open.xml	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/svc/profile/generic_open.xml	Thu Mar 08 17:32:28 2007 -0800
@@ -20,7 +20,7 @@
    
     CDDL HEADER END
    
-    Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+    Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     Use is subject to license terms.
 
     ident	"%Z%%M%	%I%	%E% SMI"
@@ -129,9 +129,6 @@
   <service name='system/power' version='1' type='service'>
     <instance name='default' enabled='true'/>
   </service>
-  <service name='application/print/cleanup' version='1' type='service'>
-    <instance name='default' enabled='true' />
-  </service>
 
   <service name='application/management/sma' version='1' type='service'>
     <instance name='default' enabled='true' />
@@ -145,10 +142,15 @@
   <service name='application/management/wbem' version='1' type='service'>
     <instance name='default' enabled='true' />
   </service>
-
   <service name='application/print/ipp-listener' version='1' type='service'>
     <instance name='default' enabled='true' />
   </service>
+  <service name='application/print/ppd-cache-update' version='1' type='service'>
+    <instance name='default' enabled='true' />
+  </service>
+  <service name='application/print/rfc1179' version='1' type='service'>
+    <instance name='default' enabled='true' />
+  </service>
 
   <!--
       Enable CDE services.
--- a/usr/src/cmd/svc/shell/netservices.sh	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/cmd/svc/shell/netservices.sh	Thu Mar 08 17:32:28 2007 -0800
@@ -19,7 +19,7 @@
 #
 # CDDL HEADER END
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -32,7 +32,9 @@
 BIND_FMRI=svc:/network/rpc/bind
 XSERVER_FMRI=svc:/application/x11/x11-server
 SENDMAIL_FMRI=svc:/network/smtp:sendmail
+PRINTSERVER_FMRI=svc:/application/print/server
 RFC1179_FMRI=svc:/application/print/rfc1179
+IPPLISTENER_FMRI=svc:/application/print/ipp-listener
 TTDB_FMRI=svc:/network/rpc/cde-ttdbserver
 DTLOGIN_FMRI=svc:/application/graphical-login/cde-login
 WEBCONSOLE_FMRI=svc:/system/webconsole
@@ -136,18 +138,6 @@
 	svcadm refresh $SENDMAIL_FMRI
 }
 
-set_rfc1179()
-{
-	svcprop -q $RFC1179_FMRI:default || return
-	if [ "$1" = "local" ]; then
-		val=localhost
-	else
-		val=
-	fi
-	inetadm -m $RFC1179_FMRI:default bind_addr="$val" 2>/dev/null
-	svcadm refresh $RFC1179_FMRI:default
-}
-
 set_ttdbserver()
 {
 	svcprop -q $TTDB_FMRI:tcp || return
@@ -247,7 +237,6 @@
 set_rpcbind $keyword
 set_xserver $keyword
 set_sendmail $keyword
-set_rfc1179 $keyword
 set_ttdbserver $keyword
 set_dtlogin $keyword
 set_webconsole $keyword
@@ -262,6 +251,17 @@
 then
 	# generic_open may not start inetd services on upgraded systems
 	svccfg apply /var/svc/profile/inetd_generic.xml
+
+	# disable rfc1179 and ipp-listener services if server is disabled
+	if [ "`svcprop -p restarter/state $PRINTSERVER_FMRI:default`" = \
+	    "disabled" ]
+	then
+		# need restart since refresh won't pick up new command-line
+		echo "print/server not enabled: disabling print/rfc1779"
+		svcadm disable $RFC1179_FMRI:default
+		echo "print/server not enabled: disabling print/ipp-listener"
+		svcadm disable $IPPLISTENER_FMRI:default
+	fi
 fi
 
 #
--- a/usr/src/lib/libsecdb/exec_attr.txt	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/lib/libsecdb/exec_attr.txt	Thu Mar 08 17:32:28 2007 -0800
@@ -237,6 +237,7 @@
 Printer Management:suser:cmd:::/usr/sbin/lpmove:euid=lp
 Printer Management:suser:cmd:::/usr/sbin/lpshut:euid=lp
 Printer Management:suser:cmd:::/usr/sbin/lpusers:euid=lp
+Printer Management:suser:cmd:::/usr/sbin/ppdmgr:euid=0
 Printer Management:suser:cmd:::/usr/ucb/lpq:euid=0
 Printer Management:suser:cmd:::/usr/ucb/lprm:euid=0
 Process Management:solaris:cmd:::/usr/bin/kill:privs=proc_owner
--- a/usr/src/lib/print/mod_ipp/ipp-listener.xml	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/lib/print/mod_ipp/ipp-listener.xml	Thu Mar 08 17:32:28 2007 -0800
@@ -21,7 +21,7 @@
 -->
 <!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
 <!--
- Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  Use is subject to license terms.
 
     pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -53,7 +53,7 @@
 	    exec='/bin/pkill -f httpd-standalone-ipp.conf'
 	    timeout_seconds='5' />
 
-	<instance name='default' enabled='true' />
+	<instance name='default' enabled='false' />
 
 	<stability value='Unstable' />
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWppm/preremove	Thu Mar 08 17:32:28 2007 -0800
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+# Remove ppdmgr created cache files
+/bin/rm -f $BASEDIR/var/lp/ppd/caches/*
+/bin/rm -f $BASEDIR/var/lp/ppd/ppdcache
+
+exit 0
--- a/usr/src/pkgdefs/SUNWppm/prototype_com	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/pkgdefs/SUNWppm/prototype_com	Thu Mar 08 17:32:28 2007 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 # 
 # This required package information file contains a list of package contents.
@@ -36,6 +35,8 @@
 i pkginfo
 i copyright
 i depend
+i preremove
+
 #
 # source locations relative to the prototype file
 #
@@ -57,7 +58,8 @@
 f none usr/sadm/admin/printmgr/classes/pmserver.jar 644 root lp
 f none usr/sadm/admin/printmgr/classes/pmclient.jar 644 root lp
 #
-# Scripts for PPD files
+# Scripts and files for ppdmgr
+#
 d none usr/lib 755 root bin
 d none usr/lib/lp 755 root lp
 d none usr/lib/lp/bin 755 root lp
@@ -69,4 +71,11 @@
 f none usr/lib/lp/bin/printer-info 555 root lp
 #
 d none usr/sbin 755 root bin
+f none usr/sbin/ppdmgr 0555 root lp
 s none usr/sbin/printmgr=../../usr/sadm/admin/bin/printmgr
+#
+d none var 755 root sys
+d none var/lp 775 lp lp
+d none var/lp/ppd 755 root lp
+d none var/lp/ppd/caches 755 root lp
+f none var/lp/ppd/manufaliases 444 root lp
--- a/usr/src/pkgdefs/SUNWpsr/postinstall	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/pkgdefs/SUNWpsr/postinstall	Thu Mar 08 17:32:28 2007 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -30,10 +29,50 @@
 # If appropriate, enable this service.
 #
 BASEPREFIX=`echo $BASEDIR | sed "s/\//_/g"`
-FILENAME=`echo sunwpsr_lpsched"$BASEPREFIX" | cut -c 1-256`
-TMPFILE=/tmp/$FILENAME
-if [ -f $TMPFILE ]; then
+LPFILENAME=`echo sunwpsr_lpsched"$BASEPREFIX" | cut -c 1-256`
+LPTMPFILE=/tmp/$LPFILENAME
+if [ -f $LPTMPFILE ]; then
 	echo "/usr/sbin/svcadm enable application/print/server" >> \
 	    $BASEDIR/var/svc/profile/upgrade
-	rm $TMPFILE
+	rm $LPTMPFILE
 fi
+
+PPDFILENAME=`echo sunwpsr_ppd_cache_update"$BASEPREFIX" | cut -c 1-256`
+PPDTMPFILE=/tmp/$PPDFILENAME
+if [ -f $PPDTMPFILE ] ; then
+
+	# Enable the ppd-cache-update service.
+	echo "/usr/sbin/svcadm enable application/print/ppd-cache-update" >> \
+	    $BASEDIR/var/svc/profile/upgrade
+
+	# Ensure pre-existing printer configuration files with an
+	# old system PPD file delivery location are updated to
+	# reflect the newest location of PPD files.
+	NEW_PATH=/usr/share/ppd
+	if [ -d $NEW_PATH ] ; then
+		OLD_PATH=/usr/lib/lp/model/ppd/system
+		PNTRS=$BASEDIR/etc/lp/printers
+		for f in `/bin/find $PNTRS -name configuration 2>/dev/null` ; do
+		    /bin/grep ${OLD_PATH} ${f} >/dev/null 2>&1
+			if [ $? -eq 0 ] ; then
+				/bin/sed \
+		    -e "s;${OLD_PATH}/foomatic;${NEW_PATH}/SUNWfoomatic;g" \
+		    -e "s;${OLD_PATH}/gimp;${NEW_PATH}/SUNWgimp;g" \
+                    -e "s;${OLD_PATH}/hpijs;${NEW_PATH}/SUNWhpijs;g" \
+		    ${f} >/tmp/lp.$$
+				/bin/mv -f /tmp/lp.$$ ${f}
+			fi
+		done
+		rm $PPDTMPFILE
+	fi
+fi
+
+# This works around the problem of legacy cleanup service removal until
+# r.manifest is fixed to work on alternate pkg root.
+if [ "${PKG_INSTALL_ROOT:-/}" != "/" ] ; then
+	echo "/usr/sbin/svccfg delete -f svc:/application/print/cleanup" >> \
+	    $BASEDIR/var/svc/profile/upgrade
+	
+fi
+
+exit 0
--- a/usr/src/pkgdefs/SUNWpsr/preinstall	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/pkgdefs/SUNWpsr/preinstall	Thu Mar 08 17:32:28 2007 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,31 +19,46 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
 #
 
-#
-# If we are upgrading a system with smf(5) already installed, then we
-# won't take any action.  Otherwise, if there are local print queues,
-# the service was enabled, preserve that.
-#
 if [ "$UPDATE" = "yes" ]; then
 	BASEPREFIX=`echo $BASEDIR | sed "s/\//_/g"`
 
-	FILENAME=`echo sunwpsr_lpsched"$BASEPREFIX" | cut -c 1-256`
-	TMPFILE=/tmp/$FILENAME
-        if [ -f $TMPFILE ]; then
-                rm $TMPFILE
-        fi
+	MANIFESTDIR="$BASEDIR/var/svc/manifest/application/print"
+	LPFILENAME=`echo sunwpsr_lpsched"$BASEPREFIX" | cut -c 1-256`
+	PPDFILENAME=`echo sunwpsr_ppd_cache_update"$BASEPREFIX" | cut -c 1-256`
+	LPTMPFILE=/tmp/$LPFILENAME
+	PPDTMPFILE=/tmp/$PPDFILENAME
 
-	if [ ! -f $BASEDIR/var/svc/manifest/application/print/server.xml ]; then
+	if [ -f $LPTMPFILE ] ; then
+		rm $LPTMPFILE
+	fi
+	if [ -f $PPDTMPFILE ] ; then
+		rm $PPDTMPFILE
+	fi
+
+	#
+	# If we are upgrading a system with smf(5) already installed, then we
+	# won't take any action.  Otherwise, if there are local print queues,
+	# the service was enabled, preserve that.
+	#
+	if [ ! -f $MANIFESTDIR/server.xml ]; then
 		queues=`echo $BASEDIR/etc/lp/printers/*/configuration`
 		if [ "$queues" != "$BASEDIR/etc/lp/printers/*/configuration" ];
 		then
-			touch $TMPFILE
+			touch $LPTMPFILE
 		fi
 	fi
+
+	#
+	# If we are upgrading a system with ppd-cache-update service already
+	# installed, then don't take any action in postinstall script.
+	#
+	if [ ! -f $MANIFESTDIR/ppd-cache-update.xml ] ; then
+		touch $PPDTMPFILE
+	fi
 fi
--- a/usr/src/pkgdefs/SUNWpsr/prototype_com	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/pkgdefs/SUNWpsr/prototype_com	Thu Mar 08 17:32:28 2007 -0800
@@ -20,7 +20,7 @@
 #
 
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -59,6 +59,8 @@
 d none var/svc/manifest/application 755 root sys
 d none var/svc/manifest/application/print 755 root sys
 f manifest var/svc/manifest/application/print/server.xml 0444 root sys
+#	Manifest for updating the ppdcache
+f manifest var/svc/manifest/application/print/ppd-cache-update.xml 0444 root sys
 #	LP configuation
 d none etc 755 root sys
 d none etc/lp 775 lp lp
@@ -106,4 +108,6 @@
 d none lib/svc 0755 root bin
 d none lib/svc/method 0755 root bin
 f none lib/svc/method/print-svc 0555 root bin
-
+#
+#	Method for updating the ppdcache
+f none lib/svc/method/ppd-cache-update 0555 root bin
--- a/usr/src/tools/scripts/bfu.sh	Thu Mar 08 17:24:46 2007 -0800
+++ b/usr/src/tools/scripts/bfu.sh	Thu Mar 08 17:32:28 2007 -0800
@@ -1033,6 +1033,7 @@
 
 # Obsolete smf manifests
 smf_obsolete_manifests="
+	var/svc/manifest/application/print/cleanup.xml
 	var/svc/manifest/network/tftp.xml
 	var/svc/manifest/network/lp.xml
 	var/svc/manifest/system/filesystem/volfs.xml
@@ -1048,6 +1049,7 @@
 
 # Obsolete smf methods
 smf_obsolete_methods="
+	lib/svc/method/print-cleanup
 	lib/svc/method/print-server
 	lib/svc/method/svc-volfs
 	lib/svc/method/pfil