xref: /onnv-gate/usr/src/cmd/print/scripts/ppdmgr (revision 3781)
1*3781Sceastha#!/bin/ksh
2*3781Sceastha#
3*3781Sceastha# CDDL HEADER START
4*3781Sceastha#
5*3781Sceastha# The contents of this file are subject to the terms of the
6*3781Sceastha# Common Development and Distribution License (the "License").
7*3781Sceastha# You may not use this file except in compliance with the License.
8*3781Sceastha#
9*3781Sceastha# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*3781Sceastha# or http://www.opensolaris.org/os/licensing.
11*3781Sceastha# See the License for the specific language governing permissions
12*3781Sceastha# and limitations under the License.
13*3781Sceastha#
14*3781Sceastha# When distributing Covered Code, include this CDDL HEADER in each
15*3781Sceastha# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*3781Sceastha# If applicable, add the following below this CDDL HEADER, with the
17*3781Sceastha# fields enclosed by brackets "[]" replaced with your own identifying
18*3781Sceastha# information: Portions Copyright [yyyy] [name of copyright owner]
19*3781Sceastha#
20*3781Sceastha# CDDL HEADER END
21*3781Sceastha#
22*3781Sceastha# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*3781Sceastha# Use is subject to license terms.
24*3781Sceastha#
25*3781Sceastha# ident	"%Z%%M%	%I%	%E% SMI"
26*3781Sceastha#
27*3781Sceastha
28*3781Sceastha#
29*3781Sceastha# Description: Script to generate the Solaris printmgr 'ppdcache' file from the
30*3781Sceastha#              ppd files installed in the given ppd database directory
31*3781Sceastha#
32*3781Sceastha# ppdmgr -a <ppd_filename_path> [ -L <label> ] [-w]
33*3781Sceastha# ppdmgr -g <ppd_filename_path> [ -L <label> ] [ -R <ppd_repository> ]
34*3781Sceastha# ppdmgr -r [ -L <label> ] [ -R <ppd_repository> ]
35*3781Sceastha# ppdmgr -u [ -L <label> ] [ -R <ppd_repository> ]
36*3781Sceastha#
37*3781Sceastha# Options:
38*3781Sceastha#		-a <ppd_filename_path>	- Add a new PPD file to the specified
39*3781Sceastha#					label in the "user" repository, and
40*3781Sceastha#					updates to the "user" repository
41*3781Sceastha#					in the ppdcache.
42*3781Sceastha#		-g <ppd_filename_path>	- Generate a cache file entry
43*3781Sceastha#					for the specified PPD file
44*3781Sceastha#					on standard out.
45*3781Sceastha#		-L <label>		- Label name.  <label>
46*3781Sceastha#					can be any characters from the
47*3781Sceastha#					portable character set, however
48*3781Sceastha#					may not contain a semi-colon (':').
49*3781Sceastha#					The following are the defaults
50*3781Sceastha#					for <label> for each option:
51*3781Sceastha#					OPTION	DEFAULT LABEL
52*3781Sceastha#					------	-------------
53*3781Sceastha#					-a	<label> from <ppd_filename_path>
54*3781Sceastha#						if <ppd_filename_path>
55*3781Sceastha#						is from a known repository,
56*3781Sceastha#						otherwise defaults to "user".
57*3781Sceastha#					-g	<label> from <ppd_filename_path>
58*3781Sceastha#						if <ppd_filename_path>
59*3781Sceastha#						is from a known repository,
60*3781Sceastha#						otherwise defaults to "user".
61*3781Sceastha#					-r	all
62*3781Sceastha#					-u	all
63*3781Sceastha#					The following are reserved labels:
64*3781Sceastha#					caches		- may never be specified
65*3781Sceastha#					ppdcache	- may never be specified
66*3781Sceastha#					manufaliases	- may never be specified
67*3781Sceastha#					all		- applies specified
68*3781Sceastha#							action to all labels
69*3781Sceastha#							in a repository.
70*3781Sceastha#							Can only be specified
71*3781Sceastha#							with -r or -u.
72*3781Sceastha#					SUNW*		- anything starting with
73*3781Sceastha#							SUNW is reserved for
74*3781Sceastha#							use by Sun, but not
75*3781Sceastha#							prohibited.
76*3781Sceastha#		-r			- Rebuild the cache information for the
77*3781Sceastha#					specified label in the specified
78*3781Sceastha#					repository.  Similar to -u, however,
79*3781Sceastha#					the cache file is removed to force an
80*3781Sceastha#					update to the ppdcache.
81*3781Sceastha#		-R <ppd_repository>	- PPD repository name.
82*3781Sceastha#					Defaults to "user".
83*3781Sceastha#					The following are the possible
84*3781Sceastha#					values for <ppd_repository> and
85*3781Sceastha#					location in the system:
86*3781Sceastha#					REP	LOCATION
87*3781Sceastha#					---	--------
88*3781Sceastha#					user	/var/lp/ppd
89*3781Sceastha#					admin	/usr/local/share/ppd
90*3781Sceastha#					vendor	/opt/share/ppd
91*3781Sceastha#					system	/usr/share/ppd
92*3781Sceastha#					all	all repositories
93*3781Sceastha#
94*3781Sceastha#					Note: When specified with the -a option
95*3781Sceastha#					only "user" and "admin" are valid.
96*3781Sceastha#					"vendor", "system", and "all" will be
97*3781Sceastha#					considered reserved.
98*3781Sceastha#		-u			- Update the PPD cache information
99*3781Sceastha#					for the specified label in the specified
100*3781Sceastha#					repository if needed.  If the cache
101*3781Sceastha#					update was required, then the updated
102*3781Sceastha#					cache information is reflected in
103*3781Sceastha#					the ppdcache.
104*3781Sceastha#		-w			- Display full path of where the
105*3781Sceastha#					ppd file is located on the system.
106*3781Sceastha#					Only valid with -a, otherwise the
107*3781Sceastha#					option is ignored.
108*3781Sceastha#
109*3781Sceastha# If -a, -g, -r, or -u are specified on the command line, only the last action
110*3781Sceastha# specified will be performed.
111*3781Sceastha#
112*3781Sceastha# Cache file entry format:
113*3781Sceastha#	<ModifiedManufacturerName>:<Model>:<NickName>:<1284DeviceIDManufacturer>:<1284DeviceIDModel>:<FullPPDFilePath>
114*3781Sceastha#	HP:HP DeskJet 450:Foomatic/hpijs (recommended):dj450:hp:/usr/share/ppd/HP/HP-DeskJet_450-hpijs.ppd.gz
115*3781Sceastha#
116*3781Sceastha
117*3781SceasthaPATH=/bin:/usr/bin:/usr/sbin export PATH
118*3781Sceasthaset -o noclobber
119*3781Sceastha
120*3781SceasthaTEXTDOMAIN="SUNW_OST_OSCMD"
121*3781Sceasthaexport TEXTDOMAIN
122*3781Sceastha
123*3781Sceastha#
124*3781Sceastha# Generates debug output for calling routine.
125*3781Sceastha# If calling routine's name is passed in, then
126*3781Sceastha# will also generate the name of the calling routine.
127*3781Sceastha#
128*3781Sceastha# $1	- Name of calling routine
129*3781Sceasthadebugger()
130*3781Sceastha{
131*3781Sceastha	[[ ${debug} -eq 1 ]] || return 1
132*3781Sceastha	if [[ -n "${1}" ]] ; then
133*3781Sceastha		echo "In ${1}..." 1>&2
134*3781Sceastha	fi
135*3781Sceastha	return 0
136*3781Sceastha}
137*3781Sceastha
138*3781Sceastha#
139*3781Sceastha# Set the ownership and permissions on a file.
140*3781Sceastha#
141*3781Sceastha# $1	- Mode
142*3781Sceastha# $2	- Owner:Group
143*3781Sceastha# $3	- Full path to file
144*3781Sceastha#
145*3781Sceasthaset_perms()
146*3781Sceastha{
147*3781Sceastha	/bin/chmod -f ${1} "${3}" >/dev/null 2>&1
148*3781Sceastha	/bin/chown -f ${2} "${3}" >/dev/null 2>&1
149*3781Sceastha}
150*3781Sceastha
151*3781Sceastha#
152*3781Sceastha# Create administrator repository directories, /usr/local/share/ppd,
153*3781Sceastha# if needed. This is a special case a Solaris doesn't deliver
154*3781Sceastha# /usr/local/share and it has different permissions than the
155*3781Sceastha# user repository.
156*3781Sceastha#
157*3781Sceastha# $1	- destination repository name
158*3781Sceastha#
159*3781Sceasthacreate_adminrep_dirs()
160*3781Sceastha{
161*3781Sceastha	if debugger "check_adminrep_dirs" ; then
162*3781Sceastha		set -x
163*3781Sceastha	fi
164*3781Sceastha
165*3781Sceastha	# Only create administrator repository directories, if needed.
166*3781Sceastha	[[ "${1}" = "${ADMIN}" ]] || return 0
167*3781Sceastha
168*3781Sceastha	# Check /usr/local/share/ppd
169*3781Sceastha	[[ ! -d "${ADMINREP}" ]] || return 0
170*3781Sceastha
171*3781Sceastha	# Check /usr/local/share
172*3781Sceastha	admpar=$(/bin/dirname "${ADMINREP}")
173*3781Sceastha	if [[ ! -d "${admpar}" ]] ; then
174*3781Sceastha
175*3781Sceastha		# Check /usr/local
176*3781Sceastha		admppar=$(/bin/dirname "${admpar}")
177*3781Sceastha		if [[ ! -d "${admppar}" ]] ; then
178*3781Sceastha			make_dir ${DIRMODE} ${ADMINOWNER} "${admppar}" || \
179*3781Sceastha			    return 1
180*3781Sceastha		fi
181*3781Sceastha		make_dir ${DIRMODE} ${ADMINOWNER} "${admpar}" || return 1
182*3781Sceastha	fi
183*3781Sceastha	make_dir ${DIRMODE} ${ADMINOWNER} ${ADMINREP} || return 1
184*3781Sceastha	return 0
185*3781Sceastha}
186*3781Sceastha
187*3781Sceastha#
188*3781Sceastha# Returns full path to PPD file that was added to the system.
189*3781Sceastha#
190*3781Sceastha# $1	- Full path to source PPD file
191*3781Sceastha# $2	- PPD file name
192*3781Sceastha# $3	- Full path to repository
193*3781Sceastha# $4	- Repository name
194*3781Sceastha# $5	- Label name
195*3781Sceastha#
196*3781Sceastha# Return codes:
197*3781Sceastha#	0	- File successfully added
198*3781Sceastha#	1	- Error
199*3781Sceastha#	2	- Duplicate file already exists
200*3781Sceastha#
201*3781Sceasthaadd_ppd()
202*3781Sceastha{
203*3781Sceastha	if debugger ; then
204*3781Sceastha		set -x
205*3781Sceastha	fi
206*3781Sceastha
207*3781Sceastha	verify_ppd_file "${1}"
208*3781Sceastha	if [[ $? -ne 0 ]] ; then
209*3781Sceastha		gettext "invalid PPD file: ${1}" 2>/dev/null
210*3781Sceastha		return 3
211*3781Sceastha	fi
212*3781Sceastha
213*3781Sceastha	# The destination path can now be set
214*3781Sceastha	dstlabelpath="${3}/${5}"
215*3781Sceastha	dstmanufpath="${dstlabelpath}/${modmanuf}"
216*3781Sceastha	dstpath="${dstmanufpath}/${2}"
217*3781Sceastha
218*3781Sceastha	#
219*3781Sceastha	# If a version (either compressed or not compressed) of the PPD
220*3781Sceastha	# file exists in the destination in the label/repository,
221*3781Sceastha	# then just return as there no work to be done.
222*3781Sceastha	dst_copy_path=$(variant_copy "${1}" "${dstpath}" "${6}" "${ppdfname}")
223*3781Sceastha	ap_rc=$?
224*3781Sceastha	if [[ ${ap_rc} -ne 0 ]] ; then
225*3781Sceastha		echo "${dst_copy_path}"
226*3781Sceastha		return ${ap_rc}
227*3781Sceastha	fi
228*3781Sceastha
229*3781Sceastha	#
230*3781Sceastha	# Can only add a PPD file to the "user" or "admin" repository.
231*3781Sceastha	# Note: this check is here instead of at the top of this
232*3781Sceastha	# function as we don't want to cause an error if a user
233*3781Sceastha	# specifies the same repository and label as a the specified
234*3781Sceastha	# ppd file and the repository of the specified ppd file
235*3781Sceastha	# exists in a known repository.
236*3781Sceastha	#
237*3781Sceastha	if [[ "${4}" != "${USER}" && "${4}" != "${ADMIN}" ]] ; then
238*3781Sceastha		gettext "invalid PPD file repository name: ${4}" 2>/dev/null
239*3781Sceastha		return 3
240*3781Sceastha	fi
241*3781Sceastha
242*3781Sceastha	# Ensure destination directories exist
243*3781Sceastha	if ! create_adminrep_dirs ${4} ${DIRMODE} ${ADMINOWNER} || \
244*3781Sceastha	    ! make_dir ${DIRMODE} ${DIROWNER} "${3}" || \
245*3781Sceastha	    ! make_dir ${DIRMODE} ${DIROWNER} "${dstlabelpath}" || \
246*3781Sceastha	    ! make_dir ${DIRMODE} ${DIROWNER} "${dstmanufpath}" ; then
247*3781Sceastha		gettext "unable to create destination directories" 2>/dev/null
248*3781Sceastha		return 3
249*3781Sceastha	fi
250*3781Sceastha
251*3781Sceastha	# Copy source PPD file, and compress if needed, to destination
252*3781Sceastha	if [[ "${ppdfileext}" = "${PEXT}" ]] ; then
253*3781Sceastha		${GZIP} "${1}" >"${dst_copy_path}" 2>/dev/null
254*3781Sceastha		if [[ $? -eq 1 ]] ; then
255*3781Sceastha			gettext "unable to copy PPD file " 2>/dev/null
256*3781Sceastha			gettext "to destination" 2>/dev/null
257*3781Sceastha			return 3
258*3781Sceastha		fi
259*3781Sceastha	else
260*3781Sceastha		/bin/cp -f "${1}" "${dst_copy_path}" >/dev/null 2>&1
261*3781Sceastha		if [[ $? -ne 0 ]] ; then
262*3781Sceastha			gettext "unable to copy PPD file " 2>/dev/null
263*3781Sceastha			gettext "to destination" 2>/dev/null
264*3781Sceastha			return 3
265*3781Sceastha		fi
266*3781Sceastha	fi
267*3781Sceastha	set_perms ${FILEMODE} ${FILEOWNER} "${dst_copy_path}"
268*3781Sceastha
269*3781Sceastha	echo "${dst_copy_path}"
270*3781Sceastha
271*3781Sceastha	return 0
272*3781Sceastha}
273*3781Sceastha
274*3781Sceastha#
275*3781Sceastha# Returns 0 if the cache needs to be modified, otherwise
276*3781Sceastha# returns 1.
277*3781Sceastha#
278*3781Sceastha# $1	- Full path to cache
279*3781Sceastha# $2	- Full path to cache replacement candidate
280*3781Sceastha#
281*3781Sceasthachanges_in_cache()
282*3781Sceastha{
283*3781Sceastha	if debugger "changes_in_cache" ; then
284*3781Sceastha		set -x
285*3781Sceastha	fi
286*3781Sceastha
287*3781Sceastha	if [[ "${action}" = "${REBUILD}" ]] ; then
288*3781Sceastha		return 0
289*3781Sceastha	fi
290*3781Sceastha	[[ "${2}" -nt "${1}" ]] || return 1
291*3781Sceastha	if $(${CMP} "${1}" "${2}" >/dev/null 2>&1) ; then
292*3781Sceastha		# No differences.  Just update timestamp
293*3781Sceastha		/bin/touch -r "${2}" "${1}" >/dev/null 2>&1
294*3781Sceastha		return 1
295*3781Sceastha	else
296*3781Sceastha		return 0
297*3781Sceastha	fi
298*3781Sceastha}
299*3781Sceastha
300*3781Sceastha#
301*3781Sceastha# Generate a new golden cache file (/var/lp/ppd/ppdcache),  by
302*3781Sceastha# concatenating and sorting all existing cache files in /var/lp/ppd/caches.
303*3781Sceastha#
304*3781Sceastha# If there are difference between the newly generated golden cache file and
305*3781Sceastha# the existing one (if it exists) then the newly generated one replaces the
306*3781Sceastha# existing one at /var/lp/ppd/ppdcache.
307*3781Sceastha#
308*3781Sceasthaupdate_golden_cache()
309*3781Sceastha{
310*3781Sceastha
311*3781Sceastha	if debugger "update_golden_cache" ; then
312*3781Sceastha		set -x
313*3781Sceastha	fi
314*3781Sceastha
315*3781Sceastha	#
316*3781Sceastha	# Remove any cache files that don't have an associated
317*3781Sceastha	# label.
318*3781Sceastha	#
319*3781Sceastha	for cname in $(/bin/ls ${VARCACHES} 2>/dev/null) ; do
320*3781Sceastha		repname="${cname%%:*}"
321*3781Sceastha		cfile="${cname#*:}"
322*3781Sceastha		checkdir="$(get_rep_path ${repname})/${cfile}"
323*3781Sceastha		remove_unassociated_cache "${checkdir}" "${cname}"
324*3781Sceastha	done
325*3781Sceastha
326*3781Sceastha	#
327*3781Sceastha	# Combine the contents of all cache files into a
328*3781Sceastha	# temporary golden cache file.
329*3781Sceastha	#
330*3781Sceastha	tmpgoldencache=$(/bin/mktemp -p "${ppdmgrtmpdir}" \
331*3781Sceastha	    tmpgoldencache.XXXXXX 2>/dev/null)
332*3781Sceastha	/bin/sort "${VARCACHES}"/* >>"${tmpgoldencache}" 2>/dev/null
333*3781Sceastha
334*3781Sceastha	if [[ ! -s "${tmpgoldencache}" ]] ; then
335*3781Sceastha		# No cache files. Remove golden cache.
336*3781Sceastha		/bin/rm -f "${GOLDCACHE}" >/dev/null 2>&1
337*3781Sceastha		/bin/rm -f "${tmpgoldencache}" >/dev/null 2>&1
338*3781Sceastha	elif [[ -e "${GOLDCACHE}" ]] ; then
339*3781Sceastha		#
340*3781Sceastha		# Use the newly generated "temporary" golden cache file if there
341*3781Sceastha		# differences between the current and newly generated ppdcache
342*3781Sceastha		# or if a rebuild is being performed.
343*3781Sceastha		#
344*3781Sceastha		if [[ "${VARCACHES}" -nt "${GOLDCACHE}" ]] || \
345*3781Sceastha		    changes_in_cache "${GOLDCACHE}" "${tmpgoldencache}" ; then
346*3781Sceastha			set_perms ${FILEMODE} ${FILEOWNER} "${tmpgoldencache}"
347*3781Sceastha			/bin/mv -f "${tmpgoldencache}" \
348*3781Sceastha			    "${GOLDCACHE}" >/dev/null 2>&1
349*3781Sceastha		else
350*3781Sceastha			/bin/rm -f "${tmpgoldencache}" >/dev/null 2>&1
351*3781Sceastha		fi
352*3781Sceastha	else
353*3781Sceastha		# There wasn't an existing ppdcache.  Install the newly
354*3781Sceastha		# generated ppdcache file to the golden ppdcache.
355*3781Sceastha		set_perms ${FILEMODE} ${FILEOWNER} "${tmpgoldencache}"
356*3781Sceastha		/bin/mv -f "${tmpgoldencache}" "${GOLDCACHE}" >/dev/null 2>&1
357*3781Sceastha	fi
358*3781Sceastha}
359*3781Sceastha
360*3781Sceastha#
361*3781Sceastha# Returns a list of PPD files that exist.
362*3781Sceastha#
363*3781Sceastha# $1	- Full path to cache file
364*3781Sceastha#
365*3781Sceastharemove_invalid_cache_entries()
366*3781Sceastha{
367*3781Sceastha	if debugger ; then
368*3781Sceastha		set -x
369*3781Sceastha	fi
370*3781Sceastha
371*3781Sceastha	[[ -s "${1}" ]] || return
372*3781Sceastha
373*3781Sceastha	IFS="$NoSpaceTabIFS"
374*3781Sceastha	for centry in $(/bin/cat "${1}" 2>/dev/null) ; do
375*3781Sceastha		IFS="$SaveIFS"
376*3781Sceastha		#
377*3781Sceastha		# Keep the entry from the ppd cache if it still
378*3781Sceastha		# exists and there haven't been any modifications
379*3781Sceastha		# since the last update to the cache.
380*3781Sceastha		#
381*3781Sceastha		if [[ -n "${centry}" ]] ; then
382*3781Sceastha			ppdfile="${centry##*:}"
383*3781Sceastha			if [[ -n "${ppdfile}" && -e "${ppdfile}"  &&
384*3781Sceastha			    "${1}" -nt "${ppdfile}" ]] ; then
385*3781Sceastha				echo "${centry}"
386*3781Sceastha			fi
387*3781Sceastha		fi
388*3781Sceastha		IFS="$NoSpaceTabIFS"
389*3781Sceastha	done
390*3781Sceastha	IFS="$SaveIFS"
391*3781Sceastha}
392*3781Sceastha
393*3781Sceastha#
394*3781Sceastha# Returns 0 if the path to the PPD is as follows:
395*3781Sceastha#	<PPD file repository>/<label>/<manufacturer>/<PPD file>
396*3781Sceastha# otherwise, returns 1
397*3781Sceastha#
398*3781Sceastha# $1	 Full path to PPD file
399*3781Sceastha#
400*3781Sceasthaverify_ppd_location()
401*3781Sceastha{
402*3781Sceastha	if debugger ; then
403*3781Sceastha		set -x
404*3781Sceastha	fi
405*3781Sceastha
406*3781Sceastha	 #
407*3781Sceastha	 # Strip off what should be <label>/<manufacturer>/<PPD file>
408*3781Sceastha	 # and verify the PPD file repository matches one of the
409*3781Sceastha	 # known PPD file repositories.
410*3781Sceastha	 #
411*3781Sceastha	ppd_file_repository=${1%/*/*/*}
412*3781Sceastha	found=1
413*3781Sceastha	for repository in ${REPOSITORIES} ; do
414*3781Sceastha		if [[ "${repository}" = "${ppd_file_repository}" ]] ; then
415*3781Sceastha			found=0
416*3781Sceastha			break
417*3781Sceastha		fi
418*3781Sceastha	done
419*3781Sceastha	return ${found}
420*3781Sceastha}
421*3781Sceastha
422*3781Sceastha#
423*3781Sceastha# Generate, and sort, cache entries for each PPD files in the specified
424*3781Sceastha# list to the specified file.
425*3781Sceastha#
426*3781Sceastha# $1	- List of full paths to PPD files
427*3781Sceastha# $2	- Full path to current cache file
428*3781Sceastha# $3	- Full path to label
429*3781Sceastha# $4	- Full path to new cache file to generate
430*3781Sceastha#
431*3781Sceastha# Return code:
432*3781Sceastha#	0 success
433*3781Sceastha#	1 unsuccessful
434*3781Sceastha#
435*3781Sceasthagenerate_label_cache_file()
436*3781Sceastha{
437*3781Sceastha	if debugger ; then
438*3781Sceastha		set -x
439*3781Sceastha	fi
440*3781Sceastha
441*3781Sceastha	#
442*3781Sceastha	# Generate a cache file containing cache entries for
443*3781Sceastha	# all files in the label.
444*3781Sceastha	#
445*3781Sceastha	ucfile=$(/bin/mktemp -p "${ppdmgrtmpdir}" \
446*3781Sceastha	    unsortedcache.XXXXXX 2>/dev/null)
447*3781Sceastha
448*3781Sceastha	#
449*3781Sceastha	# Before processing new files, remove any cache entries
450*3781Sceastha	# which may be invalid.
451*3781Sceastha	#
452*3781Sceastha	valid_files=
453*3781Sceastha	if [[ -e "${2}" && "${action}" != "${REBUILD}" ]] ; then
454*3781Sceastha		valid_files=$(remove_invalid_cache_entries "${2}")
455*3781Sceastha		if [[ -n "${valid_files}" ]] ; then
456*3781Sceastha			echo "${valid_files}" >>${ucfile}
457*3781Sceastha		fi
458*3781Sceastha	fi
459*3781Sceastha
460*3781Sceastha	#
461*3781Sceastha	# If there are no valid PPD files in the current cache file,
462*3781Sceastha	# and there are no new PPD files to process, the only thing
463*3781Sceastha	# left to do is to remove the current cache file.
464*3781Sceastha	#
465*3781Sceastha	if [[ -z "${valid_files}" && -z "${1}" ]] ; then
466*3781Sceastha		/bin/rm -f "${2}" >/dev/null 2>&1
467*3781Sceastha		/bin/rm -f "${ucfile}" >/dev/null 2>&1
468*3781Sceastha		return 0
469*3781Sceastha	fi
470*3781Sceastha
471*3781Sceastha	#
472*3781Sceastha	# For each of the label's PPD files, generate
473*3781Sceastha	# a cache file entry and add it to the cache file.
474*3781Sceastha	#
475*3781Sceastha	vpl_rc=0
476*3781Sceastha	vpf_rc=0
477*3781Sceastha	vpl_msg=
478*3781Sceastha	vpf_msg=
479*3781Sceastha	IFS="$NoSpaceTabIFS"
480*3781Sceastha	for fname in ${1} ; do
481*3781Sceastha		IFS="$SaveIFS"
482*3781Sceastha		if [[ -n "${fname}" ]] ; then
483*3781Sceastha			verify_ppd_location "${fname}"
484*3781Sceastha			vpl_rc=$?
485*3781Sceastha			if [[ ${vpl_rc} -ne 0 ]] ; then
486*3781Sceastha				vpl_msg="${vpl_msg}\t${fname}\n"
487*3781Sceastha			fi
488*3781Sceastha
489*3781Sceastha			verify_ppd_file "${fname}"
490*3781Sceastha			vpf_rc=$?
491*3781Sceastha			if [[ ${vpf_rc} -ne 0 ]] ; then
492*3781Sceastha				vpf_msg="${vpf_msg}\t${fname}\n"
493*3781Sceastha			fi
494*3781Sceastha
495*3781Sceastha			if [[ ${vpl_rc} -eq 0 && ${vpf_rc} -eq 0 ]] ; then
496*3781Sceastha				echo "$(generate_cache_file_entry \
497*3781Sceastha				    "${modmanuf}" "${model}" "${nickn}" \
498*3781Sceastha				    "${devidmfg}" "${devidmdl}" "${fname}")"
499*3781Sceastha			fi
500*3781Sceastha		fi
501*3781Sceastha		IFS="$NoSpaceTabIFS"
502*3781Sceastha	done >>"${ucfile}"
503*3781Sceastha	IFS="$SaveIFS"
504*3781Sceastha	/bin/sort -u "${ucfile}" >>"${4}" 2>/dev/null
505*3781Sceastha	/bin/rm -f "${ucfile}" >/dev/null 2>&1
506*3781Sceastha
507*3781Sceastha	[[ -n "${vpl_msg}" || -n "${vpf_msg}" ]] || return 0
508*3781Sceastha	if [[ -n ${vpl_msg} ]] ; then
509*3781Sceastha		gettext "  PPD file(s) not in valid location\n" 2>/dev/null
510*3781Sceastha		gettext \
511*3781Sceastha	    "  (<repository>/<label>/<manufacturer>/<PPD file>):\n" 2>/dev/null
512*3781Sceastha		echo "${vpl_msg}"
513*3781Sceastha	fi
514*3781Sceastha	if [[ -n ${vpf_msg} ]] ; then
515*3781Sceastha		gettext "  invalid PPD file(s):\n" 2>/dev/null
516*3781Sceastha		echo "${vpf_msg}"
517*3781Sceastha	fi
518*3781Sceastha	return 1
519*3781Sceastha}
520*3781Sceastha
521*3781Sceastha#
522*3781Sceastha# Update current cache file with candidate cache file if there are
523*3781Sceastha# differences.
524*3781Sceastha#
525*3781Sceastha# $1	- Current cache file
526*3781Sceastha# $2	- Candidate cache file to update
527*3781Sceastha# $3	- Repository name
528*3781Sceastha#
529*3781Sceasthaupdate_current_cache_file()
530*3781Sceastha{
531*3781Sceastha	if debugger "update_current_cache_file" ; then
532*3781Sceastha		set -x
533*3781Sceastha	fi
534*3781Sceastha
535*3781Sceastha	if [[ ! -s "${2}" ]] ; then
536*3781Sceastha		#
537*3781Sceastha		# Candidate cache has zero size (label
538*3781Sceastha		# directory with no PPD files under it).
539*3781Sceastha		# Delete the empty candidate cache
540*3781Sceastha		# file and delete the current cache
541*3781Sceastha		# file.
542*3781Sceastha		#
543*3781Sceastha		/bin/rm -f "${1}" >/dev/null 2>&1
544*3781Sceastha		/bin/rm -f "${2}" >/dev/null 2>&1
545*3781Sceastha	elif [[ -e "${1}" ]] ; then
546*3781Sceastha		#
547*3781Sceastha		# If there are differences between the current
548*3781Sceastha		# cache file and the newly generated one, then
549*3781Sceastha		# replace the current one with the new one, and
550*3781Sceastha		# set the flag to update the golden ppdcache
551*3781Sceastha		# file.
552*3781Sceastha		#
553*3781Sceastha		if changes_in_cache "${1}" "${2}" ; then
554*3781Sceastha			set_perms ${FILEMODE} ${FILEOWNER} "${2}"
555*3781Sceastha			/bin/mv -f "${2}" "${1}" >/dev/null 2>&1
556*3781Sceastha		else
557*3781Sceastha			/bin/rm -f "${2}" >/dev/null 2>&1
558*3781Sceastha		fi
559*3781Sceastha	else
560*3781Sceastha
561*3781Sceastha		#
562*3781Sceastha		# There is no current cache file.  Move the candidate
563*3781Sceastha		# to the caches directory.
564*3781Sceastha		#
565*3781Sceastha		set_perms ${FILEMODE} ${FILEOWNER} "${2}"
566*3781Sceastha		/bin/mv -f "${2}" "${1}" >/dev/null 2>&1
567*3781Sceastha	fi
568*3781Sceastha}
569*3781Sceastha
570*3781Sceastha#
571*3781Sceastha# Returns 0 if there are files in $1 with newer timestamp
572*3781Sceastha# than $2 or if deletions have occurred under $1,
573*3781Sceastha# otherwise returns 1.
574*3781Sceastha#
575*3781Sceastha# $1	- Full path to the destination label
576*3781Sceastha# $2	- Full path to label cache file
577*3781Sceastha#
578*3781Sceasthachanges_under_label()
579*3781Sceastha{
580*3781Sceastha	if debugger ; then
581*3781Sceastha		set -x
582*3781Sceastha	fi
583*3781Sceastha
584*3781Sceastha	# First check for newer files in the directory
585*3781Sceastha	if [[ -e "${2}" && "${action}" != "${REBUILD}" ]] ; then
586*3781Sceastha		newfiles=$(/bin/find "${1}" -type f -newer "${2}")
587*3781Sceastha	else
588*3781Sceastha		newfiles=$(/bin/find "${1}" -type f)
589*3781Sceastha	fi
590*3781Sceastha	echo "${newfiles}"
591*3781Sceastha	[[ -z "${newfiles}" ]] || return 0
592*3781Sceastha
593*3781Sceastha	#
594*3781Sceastha	# Need to detect if PPD files have been deleted by checking
595*3781Sceastha	# timestamps on label and manufacturer directories.
596*3781Sceastha	#
597*3781Sceastha	[[ ! "${1}" -nt "${2}" ]] || return 0
598*3781Sceastha	/bin/find "${1}" -type d -newer "${2}" >/dev/null 2>&1 || return 1
599*3781Sceastha	return 0
600*3781Sceastha}
601*3781Sceastha
602*3781Sceastha#
603*3781Sceastha# If -R was specified, or the timestamp on the specified label's
604*3781Sceastha# directory or any of the PPD files under the specified label in
605*3781Sceastha# the specified PPD file respository is newer than the cache file
606*3781Sceastha# associated with the label, then generate a new sorted cache file.
607*3781Sceastha#
608*3781Sceastha# The new cache will replace the existing one (if any) only if there
609*3781Sceastha# are differences.  Note: if -r was specified, then a new cache file
610*3781Sceastha# file will always be installed at
611*3781Sceastha#	/var/lp/ppd/caches/<PPD file repository name>-<label name>
612*3781Sceastha#
613*3781Sceastha# $1	- Full path of the destination PPD file repository
614*3781Sceastha# $2	- Destination PPD file repository name
615*3781Sceastha# $3	- Destination label name
616*3781Sceastha#
617*3781Sceasthaupdate_label_cache()
618*3781Sceastha{
619*3781Sceastha	if debugger ; then
620*3781Sceastha		set -x
621*3781Sceastha	fi
622*3781Sceastha
623*3781Sceastha	dstlabelpath="${1}/${3}"
624*3781Sceastha	replabelcachepath="${1}/${CACHES}/${3}"
625*3781Sceastha	varlabelcachepath="${VARCACHES}/${2}${SEP}${3}"
626*3781Sceastha
627*3781Sceastha	ulc_rc=0
628*3781Sceastha	if [[ -d "${dstlabelpath}" ]] ; then
629*3781Sceastha
630*3781Sceastha		#
631*3781Sceastha		# If the cache doesn't exist for a label,
632*3781Sceastha		# or if there were any changes under a label
633*3781Sceastha		# (i.e., the timestamp on the label directory or any
634*3781Sceastha		# of the PPD files under it is newer than the
635*3781Sceastha		# existing cache file), then generate a new cache file.
636*3781Sceastha		#
637*3781Sceastha		tmpcachepath=$(/bin/mktemp -p "${ppdmgrtmpdir}" \
638*3781Sceastha		    tmpcachepath.XXXXXX 2>/dev/null)
639*3781Sceastha		newfileslist=$(changes_under_label "${dstlabelpath}" \
640*3781Sceastha		    "${varlabelcachepath}")
641*3781Sceastha		if [[ $? -eq 0 ]] ; then
642*3781Sceastha			err_files=$(generate_label_cache_file \
643*3781Sceastha			    "${newfileslist}" "${varlabelcachepath}" \
644*3781Sceastha			    "${dstlabelpath}" "${tmpcachepath}")
645*3781Sceastha			if [[ $? -ne 0 ]] ; then
646*3781Sceastha				#
647*3781Sceastha				# At least one PPD file was invalid.
648*3781Sceastha				# Don't return yet, as the cache info
649*3781Sceastha				# for the valid PPD files can still be
650*3781Sceastha				# used to generate a cache file.
651*3781Sceastha				#
652*3781Sceastha				echo "${err_files}"
653*3781Sceastha				ulc_rc=1
654*3781Sceastha			fi
655*3781Sceastha		fi
656*3781Sceastha
657*3781Sceastha		if [[ -e "${tmpcachepath}" ]] ; then
658*3781Sceastha			update_current_cache_file \
659*3781Sceastha			    "${varlabelcachepath}" "${tmpcachepath}" "${2}"
660*3781Sceastha			/bin/rm -f "${tmpcachepath}" >/dev/null 2>&1
661*3781Sceastha		fi
662*3781Sceastha	else
663*3781Sceastha		#
664*3781Sceastha		# If there is a cache file in /var/lp/ppd/caches associated
665*3781Sceastha		# with the label which no longer exists, remove it.
666*3781Sceastha		#
667*3781Sceastha		/bin/rm -f "${varlabelcachepath}" >/dev/null 2>&1
668*3781Sceastha	fi
669*3781Sceastha	return ${ulc_rc}
670*3781Sceastha}
671*3781Sceastha
672*3781Sceastha#
673*3781Sceastha# Returns the alias for the specified real manufacturer's name.
674*3781Sceastha#
675*3781Sceastha# $1	- Real manufacturer's name
676*3781Sceastha# $2	- File containing list of files that have manufacturers aliases
677*3781Sceastha#
678*3781Sceasthamanuf_name_alias()
679*3781Sceastha{
680*3781Sceastha	if debugger ; then
681*3781Sceastha		set -x
682*3781Sceastha	fi
683*3781Sceastha
684*3781Sceastha	#
685*3781Sceastha	# Found a couple of PPD files which had special characters
686*3781Sceastha	# in the Manufacturer name (i.e, the following is the Manufacturer
687*3781Sceastha	# entry:
688*3781Sceastha	#	*Manufacturer:  "Canon Inc. (Kosugi Offic"
689*3781Sceastha	# We'll only search the alias file for "Canon Inc."
690*3781Sceastha	#
691*3781Sceastha	tmpmanuf="${1% *\(*}"
692*3781Sceastha
693*3781Sceastha	# Search alias files for a match on the real manufacturer name
694*3781Sceastha	if [[ -s "${2}" ]] ; then
695*3781Sceastha		#
696*3781Sceastha		# Check the manufacturer aliases file for case
697*3781Sceastha		# insensitive match of the Manufacturer entry
698*3781Sceastha		# from the PPD file.  If a match is found,
699*3781Sceastha		# then modify the manufacturer entry to
700*3781Sceastha		# be that of the specified alias.
701*3781Sceastha		#
702*3781Sceastha		manufaliases=$(/bin/egrep -i \
703*3781Sceastha		    "^${tmpmanuf}:|:${tmpmanuf}:|:${tmpmanuf}$" "${2}")
704*3781Sceastha		if [[ -n "${manufaliases}" ]] ; then
705*3781Sceastha			echo "${manufaliases%%:*}"
706*3781Sceastha			break
707*3781Sceastha		else
708*3781Sceastha			echo "${tmpmanuf}"
709*3781Sceastha		fi
710*3781Sceastha	else
711*3781Sceastha		echo "${tmpmanuf}"
712*3781Sceastha	fi
713*3781Sceastha}
714*3781Sceastha
715*3781Sceastha#
716*3781Sceastha# Returns 0 if the extension to the specified PPD file is a known
717*3781Sceastha# extension, otherwise returns 1.
718*3781Sceastha#
719*3781Sceastha# $1	- Full path to PPD file
720*3781Sceastha#
721*3781Sceastha# Set upon return:
722*3781Sceastha#	ppdfileext	- PPD file ext (.ppd or .ppd.gz)
723*3781Sceastha#
724*3781Sceasthaverify_file_ext()
725*3781Sceastha{
726*3781Sceastha	if debugger ; then
727*3781Sceastha		set -x
728*3781Sceastha	fi
729*3781Sceastha
730*3781Sceastha	if [[ "${1%.gz}".gz = "${1}" ]] ; then
731*3781Sceastha		ppdfileext=${GEXT}
732*3781Sceastha	elif [[ "${1%.ppd}".ppd = "${1}" ]] ; then
733*3781Sceastha		ppdfileext=${PEXT}
734*3781Sceastha	else
735*3781Sceastha		# invalid PPD file name extension
736*3781Sceastha		return 1
737*3781Sceastha	fi
738*3781Sceastha
739*3781Sceastha	return 0
740*3781Sceastha}
741*3781Sceastha
742*3781Sceastha#
743*3781Sceastha# Return the lines from the specified PPD file matching the specified
744*3781Sceastha# spec items.
745*3781Sceastha#
746*3781Sceastha# $1	- spec entries from PPD file
747*3781Sceastha# $2	- spec item
748*3781Sceastha#
749*3781Sceastha# $1 example - 1 string with substrings separated by newline:
750*3781Sceastha#	*PPD-Adobe: "4.3"
751*3781Sceastha#	*Manufacturer: "HP"
752*3781Sceastha#	*Product:       "(officejet 4200 series)"
753*3781Sceastha#	*ModelName:     "HP OfficeJet 4200"
754*3781Sceastha#	*NickName:      "HP OfficeJet 4200 Foomatic/hpijs (recommended)"
755*3781Sceastha# $2 example:
756*3781Sceastha#	^\*Manufacturer
757*3781Sceastha#
758*3781Sceasthaspec_entry()
759*3781Sceastha{
760*3781Sceastha	if debugger ; then
761*3781Sceastha		set -x
762*3781Sceastha	fi
763*3781Sceastha
764*3781Sceastha	item=$(echo "${1}" | /bin/grep ${2})
765*3781Sceastha	# Remove everything up to and including the first quote
766*3781Sceastha	item=${item#*\"}
767*3781Sceastha	# Remove the end quote
768*3781Sceastha	echo "${item%\"}"
769*3781Sceastha}
770*3781Sceastha
771*3781Sceastha#
772*3781Sceastha# Return the lines from the specified PPD file matching the specified
773*3781Sceastha# spec items.
774*3781Sceastha#
775*3781Sceastha# Note: this is similar to spec_entry() except the tokens in the
776*3781Sceastha# spec entry are different.
777*3781Sceastha#
778*3781Sceastha# $1	- spec entries from PPD file
779*3781Sceastha# $2	- spec item
780*3781Sceastha#
781*3781Sceasthadevid_spec_entry()
782*3781Sceastha{
783*3781Sceastha	if debugger ; then
784*3781Sceastha		set -x
785*3781Sceastha	fi
786*3781Sceastha
787*3781Sceastha	item=$(echo "${1}" | /bin/grep ${2})
788*3781Sceastha	# Remove everything up to and including the first semi-colon
789*3781Sceastha	item=${item#*\:}
790*3781Sceastha	# Remove the end quote
791*3781Sceastha	echo ${item%\;}
792*3781Sceastha
793*3781Sceastha}
794*3781Sceastha
795*3781Sceastha#
796*3781Sceastha# Verifies that the specified PPD file
797*3781Sceastha#	- has a valid extension
798*3781Sceastha#	- has the following required spec file entries:
799*3781Sceastha#		*PPD-Adobe: "4.3"
800*3781Sceastha#		Manufacturer
801*3781Sceastha#		Product
802*3781Sceastha#		ModelName
803*3781Sceastha#		NickName
804*3781Sceastha#
805*3781Sceastha# In addition, the manufacture and model from the IEEE1284 device id
806*3781Sceastha# information will be gathered here, although it's not an error that
807*3781Sceastha# it isn't in the PPD file as many don't contain the IEEE1284 info.
808*3781Sceastha#
809*3781Sceastha# $1	- Full path to PPD file
810*3781Sceastha#
811*3781Sceastha# Return codes:
812*3781Sceastha#	0	success
813*3781Sceastha#	1	invalid PPD file
814*3781Sceastha#
815*3781Sceasthaverify_ppd_file()
816*3781Sceastha{
817*3781Sceastha	if debugger ; then
818*3781Sceastha		set -x
819*3781Sceastha	fi
820*3781Sceastha
821*3781Sceastha	ADOBESPEC="PPD-Adobe"
822*3781Sceastha	MANUF="Manufacturer"
823*3781Sceastha	PRODUCT="Product"
824*3781Sceastha	MODEL="ModelName"
825*3781Sceastha	NICKNAME="NickName"
826*3781Sceastha	DEVID="1284DeviceID"
827*3781Sceastha
828*3781Sceastha	# Verify the PPD file extension
829*3781Sceastha	verify_file_ext "${1}" || return 1
830*3781Sceastha
831*3781Sceastha	# Query for the required spec items
832*3781Sceastha	searchentries="^\*${ADOBESPEC}:|^\*${MANUF}:|^\*${PRODUCT}:"
833*3781Sceastha	searchentries="${searchentries}|^\*${MODEL}:|^\*${NICKNAME}:"
834*3781Sceastha	searchentries="${searchentries}|^\*${DEVID}:"
835*3781Sceastha	ppd_info="$(/bin/gzgrep -e "${searchentries}" "${1}")"
836*3781Sceastha
837*3781Sceastha	#
838*3781Sceastha	# Process the query results to verify each of the required spec
839*3781Sceastha	# file items appears in the PPD file.
840*3781Sceastha	#
841*3781Sceastha	for spec_item in ${ADOBESPEC} ${MANUF} ${PRODUCT} ${MODEL} \
842*3781Sceastha	    ${NICKNAME} ; do
843*3781Sceastha		entry=$(spec_entry "${ppd_info}" "^\*${spec_item}:")
844*3781Sceastha		[[ ! -z "${entry}" ]] || return 1
845*3781Sceastha		case ${spec_item} in
846*3781Sceastha		${MANUF})
847*3781Sceastha			realmanuf="${entry}"
848*3781Sceastha			;;
849*3781Sceastha		${PRODUCT})
850*3781Sceastha			product="${entry}"
851*3781Sceastha			;;
852*3781Sceastha		${MODEL})
853*3781Sceastha			model="${entry}"
854*3781Sceastha			;;
855*3781Sceastha		${NICKNAME})
856*3781Sceastha			#
857*3781Sceastha			# Remove the model and any commas and spaces
858*3781Sceastha			# which appear before the driver
859*3781Sceastha			#
860*3781Sceastha			nickn="${entry#$model[, ]*}"
861*3781Sceastha			;;
862*3781Sceastha		esac
863*3781Sceastha
864*3781Sceastha	done
865*3781Sceastha
866*3781Sceastha	# Save IEEE1284 device id information
867*3781Sceastha	if $(echo "${ppd_info}" | grep "${DEVID}" >/dev/null 2>&1) ; then
868*3781Sceastha		DMDL="MDL"
869*3781Sceastha		DMFG="MFG"
870*3781Sceastha		devid="$(/bin/gzgrep -e "^[ ]*${DMDL}:|^[ ]*${DMFG}:" "${1}")"
871*3781Sceastha		devidmdl="$(devid_spec_entry "${devid}" "${DMDL}")"
872*3781Sceastha		devidmfg="$(devid_spec_entry "${devid}" "${DMFG}")"
873*3781Sceastha	else
874*3781Sceastha		devidmdl=
875*3781Sceastha		devidmfg=
876*3781Sceastha	fi
877*3781Sceastha	modmanuf=$(manuf_name_alias "${realmanuf}" ${aliasfile})
878*3781Sceastha
879*3781Sceastha	return 0
880*3781Sceastha}
881*3781Sceastha
882*3781Sceastha#
883*3781Sceastha# generate_cache_file_entry()
884*3781Sceastha#
885*3781Sceastha# Returns a cache file entry for the specified PPD file.
886*3781Sceastha#
887*3781Sceastha# $1	- modmanuf
888*3781Sceastha# $2	- model
889*3781Sceastha# $3	- nickn
890*3781Sceastha# $4	- devidmfg
891*3781Sceastha# $5	- devidmdl
892*3781Sceastha# $6	- Full path to the specified PPD file
893*3781Sceastha#
894*3781Sceasthagenerate_cache_file_entry()
895*3781Sceastha{
896*3781Sceastha	if debugger "generate_cache_file_entry" ; then
897*3781Sceastha		set -x
898*3781Sceastha	fi
899*3781Sceastha
900*3781Sceastha	echo "${1}":"${2}":"${3}":"${4}":"${5}":"${6}"
901*3781Sceastha}
902*3781Sceastha
903*3781Sceastha#
904*3781Sceastha# Expand specified file to the full path.
905*3781Sceastha#
906*3781Sceastha# $1	- File path to expand
907*3781Sceastha#
908*3781Sceastha# Return code set to 0 if expanded successfully, otherwise set to 1.
909*3781Sceastha#
910*3781Sceasthappd_pathname()
911*3781Sceastha{
912*3781Sceastha	if debugger ; then
913*3781Sceastha		set -x
914*3781Sceastha	fi
915*3781Sceastha
916*3781Sceastha	if [[ -f "${1}" && -s "${1}" ]] ; then
917*3781Sceastha		(cd "$(/bin/dirname "${1}")" ; \
918*3781Sceastha		    echo "$(/bin/pwd)/$(/bin/basename "${1}")") || return 1
919*3781Sceastha		return 0
920*3781Sceastha	else
921*3781Sceastha		return 1
922*3781Sceastha	fi
923*3781Sceastha}
924*3781Sceastha
925*3781Sceastha#
926*3781Sceastha# Returns the PPD repsitory path associated with the specified
927*3781Sceastha# PPD repository name.
928*3781Sceastha#
929*3781Sceastha# $1	- Repository name
930*3781Sceastha#
931*3781Sceasthaget_rep_path()
932*3781Sceastha{
933*3781Sceastha	if debugger ; then
934*3781Sceastha		set -x
935*3781Sceastha	fi
936*3781Sceastha
937*3781Sceastha	case ${1} in
938*3781Sceastha	${SYSTEM})
939*3781Sceastha		echo "${SYSTEMREP}"
940*3781Sceastha		;;
941*3781Sceastha	${VENDOR})
942*3781Sceastha		echo "${VENDORREP}"
943*3781Sceastha		;;
944*3781Sceastha	${ADMIN})
945*3781Sceastha		echo "${ADMINREP}"
946*3781Sceastha		;;
947*3781Sceastha	${USER})
948*3781Sceastha		echo "${USERREP}"
949*3781Sceastha		;;
950*3781Sceastha	*)
951*3781Sceastha		echo "${UNSET}"
952*3781Sceastha		;;
953*3781Sceastha	esac
954*3781Sceastha}
955*3781Sceastha
956*3781Sceastha#
957*3781Sceastha# Returns the PPD respository name from the repository path
958*3781Sceastha#
959*3781Sceastha# $1	- PPD repository path
960*3781Sceastha#
961*3781Sceasthaget_rep_name()
962*3781Sceastha{
963*3781Sceastha	if debugger ; then
964*3781Sceastha		set -x
965*3781Sceastha	fi
966*3781Sceastha
967*3781Sceastha	case ${1} in
968*3781Sceastha	${SYSTEMREP})
969*3781Sceastha		echo "${SYSTEM}"
970*3781Sceastha		;;
971*3781Sceastha	${VENDORREP})
972*3781Sceastha		echo "${VENDOR}"
973*3781Sceastha		;;
974*3781Sceastha	${ADMINREP})
975*3781Sceastha		echo "${ADMIN}"
976*3781Sceastha		;;
977*3781Sceastha	${USERREP})
978*3781Sceastha		echo "${USER}"
979*3781Sceastha		;;
980*3781Sceastha	"all")
981*3781Sceastha		echo "all"
982*3781Sceastha		;;
983*3781Sceastha	*)
984*3781Sceastha		echo "${UNSET}"
985*3781Sceastha		;;
986*3781Sceastha	esac
987*3781Sceastha}
988*3781Sceastha
989*3781Sceastha#
990*3781Sceastha# Returns 0 if a matching label name is found in the specified repository,
991*3781Sceastha# otherwise returns 1.
992*3781Sceastha#
993*3781Sceastha# $1	- repository path
994*3781Sceastha# $2	- label name
995*3781Sceastha#
996*3781Sceasthalabel_path_in_repository()
997*3781Sceastha{
998*3781Sceastha	if debugger "label_path_in_repository" ; then
999*3781Sceastha		set -x
1000*3781Sceastha	fi
1001*3781Sceastha
1002*3781Sceastha	[[ "${1}" != "" && "${2}" != "" ]] || return 1
1003*3781Sceastha	lpir_rc=1
1004*3781Sceastha	for repository in ${REPOSITORIES} ; do
1005*3781Sceastha		if [[ "${repository}" = "${1}" && -d "${1}/${2}" ]] ; then
1006*3781Sceastha			lpir_rc=0
1007*3781Sceastha			break
1008*3781Sceastha		fi
1009*3781Sceastha	done
1010*3781Sceastha	return ${lpir_rc}
1011*3781Sceastha}
1012*3781Sceastha
1013*3781Sceastha#
1014*3781Sceastha# Returns 0 if the source label path is the same
1015*3781Sceastha# as the destination label path, otherwise returns 1.
1016*3781Sceastha#
1017*3781Sceastha# $1	- full path to source PPD file (source label path)
1018*3781Sceastha# $2	- destination repository path
1019*3781Sceastha# $3	- destination label name
1020*3781Sceastha#
1021*3781Sceasthalabel_path_match()
1022*3781Sceastha{
1023*3781Sceastha	if debugger "label_path_match" ; then
1024*3781Sceastha		set -x
1025*3781Sceastha	fi
1026*3781Sceastha
1027*3781Sceastha	# dest repository not specified
1028*3781Sceastha	if [[ "${2}" = "${UNSET}" ]] ; then
1029*3781Sceastha		# dest label not specified
1030*3781Sceastha		if [[ "${3}" = "${UNSET}" ]] ; then
1031*3781Sceastha			#
1032*3781Sceastha			# We've found a match if the label path is in a known
1033*3781Sceastha			# repository.
1034*3781Sceastha			#
1035*3781Sceastha			lpath="${1%/*/*}"
1036*3781Sceastha			label_path_in_repository \
1037*3781Sceastha			    "${1%/*/*/*}" "${lpath##*/}" || return 1
1038*3781Sceastha		else
1039*3781Sceastha			#
1040*3781Sceastha			# If the source label path exists in the
1041*3781Sceastha			# in a known repository, and the destination
1042*3781Sceastha			# label is the same as the source label,
1043*3781Sceastha			# then we'll assume the default destination
1044*3781Sceastha			# repository is the same as the source
1045*3781Sceastha			# destination repository.
1046*3781Sceastha			#
1047*3781Sceastha			[[ "${1%/*/*}" = "${1%/*/*/*}/${3}" ]] || return 1
1048*3781Sceastha			label_path_in_repository "${1%/*/*/*}" "${3}" || \
1049*3781Sceastha			    return 1
1050*3781Sceastha		fi
1051*3781Sceastha
1052*3781Sceastha	# dest repository specified, dest label not specified
1053*3781Sceastha	elif [[ "${3}" = "${UNSET}" ]] ; then
1054*3781Sceastha		#
1055*3781Sceastha		# If the destination repository path is the same as the
1056*3781Sceastha		# source repository, and if the source label exists in the
1057*3781Sceastha		# destination repository path, then we'll assume the default
1058*3781Sceastha		# destination label is the same as the source label.
1059*3781Sceastha		#
1060*3781Sceastha		[[ "${2}" = "${1%/*/*/*}" ]] || return 1
1061*3781Sceastha		lpath="${1%/*/*}"
1062*3781Sceastha		label_path_in_repository "${2}" "${lpath##*/}" || return 1
1063*3781Sceastha
1064*3781Sceastha	# dest repository and dest label specified.
1065*3781Sceastha	else
1066*3781Sceastha		#
1067*3781Sceastha		# We've found a match if the destination and label
1068*3781Sceastha		# match those of the source label path, and the source
1069*3781Sceastha		# label path is in a known repository.
1070*3781Sceastha		#
1071*3781Sceastha		[[ "${1%/*/*}" = "${2}/${3}" ]] || return 1
1072*3781Sceastha		label_path_in_repository "${2}" "${3}" || return 1
1073*3781Sceastha	fi
1074*3781Sceastha	return 0
1075*3781Sceastha}
1076*3781Sceastha
1077*3781Sceastha#
1078*3781Sceastha# Returns 0 if specified label name is a reserved label, otherwise
1079*3781Sceastha# returns 1.
1080*3781Sceastha#
1081*3781Sceastha# $1	- label name
1082*3781Sceastha#
1083*3781Sceasthareserved_label()
1084*3781Sceastha{
1085*3781Sceastha	if debugger ; then
1086*3781Sceastha		set -x
1087*3781Sceastha	fi
1088*3781Sceastha
1089*3781Sceastha	rl_rc=1
1090*3781Sceastha	for labelname in ${RESERVEDLABELS} ; do
1091*3781Sceastha		if [[ "${1}" = "${labelname}" ]] ; then
1092*3781Sceastha			rl_rc=0
1093*3781Sceastha			break
1094*3781Sceastha		fi
1095*3781Sceastha	done
1096*3781Sceastha	return ${rl_rc}
1097*3781Sceastha}
1098*3781Sceastha
1099*3781Sceastha#
1100*3781Sceastha# Returns a list of all labels that exist in a repository that are
1101*3781Sceastha# not reserved labels.
1102*3781Sceastha#
1103*3781Sceastha# $1	- Full path of repository
1104*3781Sceastha# $2	- Repository name
1105*3781Sceastha#
1106*3781Sceasthaget_rep_label_list()
1107*3781Sceastha{
1108*3781Sceastha	if debugger ; then
1109*3781Sceastha		set -x
1110*3781Sceastha	fi
1111*3781Sceastha
1112*3781Sceastha	#
1113*3781Sceastha	# Get a list of all labels that exist in all of the
1114*3781Sceastha	# PPD file repository.
1115*3781Sceastha	#
1116*3781Sceastha	for lname in $(/bin/ls "${1}" 2>/dev/null) ; do
1117*3781Sceastha		if [[ -d "${1}/${lname}" ]] ; then
1118*3781Sceastha			if ! reserved_label "${lname}" ; then
1119*3781Sceastha				echo "${lname} "
1120*3781Sceastha			fi
1121*3781Sceastha		fi
1122*3781Sceastha	done
1123*3781Sceastha}
1124*3781Sceastha
1125*3781Sceastha#
1126*3781Sceastha# Returns a valid PPD label.
1127*3781Sceastha#
1128*3781Sceastha# Verifies the specified PPD label is a valid label.  If the
1129*3781Sceastha# label is not set, then it is set to a default value.
1130*3781Sceastha#
1131*3781Sceastha# Return code set to 0 if the specified PPD label is valid, otherwise 1.
1132*3781Sceastha#
1133*3781Sceastha# $1	- PPD label
1134*3781Sceastha#
1135*3781Sceasthavalid_specified_label()
1136*3781Sceastha{
1137*3781Sceastha	if debugger ; then
1138*3781Sceastha		set -x
1139*3781Sceastha	fi
1140*3781Sceastha
1141*3781Sceastha	# Verify the specified label
1142*3781Sceastha	vsl_rc=0
1143*3781Sceastha	case "${1}" in
1144*3781Sceastha	"all")
1145*3781Sceastha		# Reserved label name with -a or -g options
1146*3781Sceastha		if [[ "${action}" = "${ADD}" || \
1147*3781Sceastha		    "${action}" = "${GENERATEENTRY}" ]] ; then
1148*3781Sceastha			print -n "$myprog: " 1>&2
1149*3781Sceastha			gettext "reserved PPD label name: ${1}\n" 1>&2
1150*3781Sceastha			vsl_rc=1
1151*3781Sceastha		else
1152*3781Sceastha			echo "${1}"
1153*3781Sceastha		fi
1154*3781Sceastha		;;
1155*3781Sceastha
1156*3781Sceastha	"ppdcache" | "caches" | "manufaliases")
1157*3781Sceastha		# Reserved label names with any option
1158*3781Sceastha		print -n "$myprog: " 1>&2
1159*3781Sceastha		gettext "reserved PPD label name: ${1}\n" 1>&2
1160*3781Sceastha		vsl_rc=1
1161*3781Sceastha		;;
1162*3781Sceastha
1163*3781Sceastha	"" | "${UNSET}")
1164*3781Sceastha		# Label name not specified.  Set the default label name.
1165*3781Sceastha		# For -g and -a, default is "user", otherwise, default
1166*3781Sceastha		# is "all".
1167*3781Sceastha		if [[ "${action}" = "${ADD}" || \
1168*3781Sceastha		    "${action}" = "${GENERATEENTRY}" ]] ; then
1169*3781Sceastha			echo "${USER}"
1170*3781Sceastha		else
1171*3781Sceastha			echo "all"
1172*3781Sceastha		fi
1173*3781Sceastha		;;
1174*3781Sceastha
1175*3781Sceastha	*)
1176*3781Sceastha		# label cannot be "." or ".."
1177*3781Sceastha		if [[ "${1}" = "." || "${1}" = ".." ]] ; then
1178*3781Sceastha			print -n "$myprog: " 1>&2
1179*3781Sceastha			gettext "PPD label name cannot be " 1>&2
1180*3781Sceastha			gettext "\".\" or \"..\"\n" 1>&2
1181*3781Sceastha			vsl_rc=1
1182*3781Sceastha		fi
1183*3781Sceastha
1184*3781Sceastha		# Label name cannot contain special characters
1185*3781Sceastha		echo "${1}" | /bin/egrep "${SPECIALCHARS}" >/dev/null
1186*3781Sceastha		if [[ $? -eq 0 ]] ; then
1187*3781Sceastha			print -n "$myprog: " 1>&2
1188*3781Sceastha			gettext "PPD label name contains " 1>&2
1189*3781Sceastha			gettext "an invalid character: ${1}\n" 1>&2
1190*3781Sceastha			vsl_rc=1
1191*3781Sceastha		else
1192*3781Sceastha			echo "${1}"
1193*3781Sceastha		fi
1194*3781Sceastha		;;
1195*3781Sceastha	esac
1196*3781Sceastha	return ${vsl_rc}
1197*3781Sceastha}
1198*3781Sceastha
1199*3781Sceastha#
1200*3781Sceastha# Returns the full path of any variant copy of the source file in
1201*3781Sceastha# the destination label/repository.
1202*3781Sceastha#
1203*3781Sceastha# $1	- Full path to source PPD file
1204*3781Sceastha# $2	- Full path to destination PPD file
1205*3781Sceastha#
1206*3781Sceastha# Return code set to
1207*3781Sceastha#	0	- Copy doesn't exist
1208*3781Sceastha#	1	- Duplicate copy exists
1209*3781Sceastha#	2	- Variant copy exists
1210*3781Sceastha#
1211*3781Sceasthavariant_copy()
1212*3781Sceastha{
1213*3781Sceastha	if debugger ; then
1214*3781Sceastha		set -x
1215*3781Sceastha	fi
1216*3781Sceastha
1217*3781Sceastha	#
1218*3781Sceastha	# First make sure there is not a .ppd and a .ppd.gz version
1219*3781Sceastha	# of the destination file; users should know not to do this.
1220*3781Sceastha	#
1221*3781Sceastha	if [[ -e "${2%.gz}" && -e "${2%.gz}.gz" ]] ; then
1222*3781Sceastha		/bin/rm -f "${2%.gz}" >/dev/null 2>&1
1223*3781Sceastha	fi
1224*3781Sceastha
1225*3781Sceastha	# Use gzcmp to compare PPD files as it can deal with
1226*3781Sceastha	# gzipped or regular files.
1227*3781Sceastha	if $(${GZCMP} "${1}" "${2}"* >/dev/null 2>&1) ; then
1228*3781Sceastha		echo "${2}"*
1229*3781Sceastha		return 1
1230*3781Sceastha	elif [[ -e "${2%.gz}" ]] ; then
1231*3781Sceastha		echo "${2%.gz}"
1232*3781Sceastha		return 2
1233*3781Sceastha	elif [[ -e "${2%.gz}.gz" ]] ; then
1234*3781Sceastha		echo "${2%.gz}.gz"
1235*3781Sceastha		return 2
1236*3781Sceastha	else
1237*3781Sceastha		#
1238*3781Sceastha		# A PPD file doesn't exist in the destination
1239*3781Sceastha		# repository under the destination label.
1240*3781Sceastha		# Just display the source PPD file, ensuring
1241*3781Sceastha		# it has a gzip extension as we will always
1242*3781Sceastha		# try to gzip the copy in the destination.
1243*3781Sceastha		#
1244*3781Sceastha		if [[ "${1#*.ppd}" = ".gz" ]] ; then
1245*3781Sceastha			echo "${2}"
1246*3781Sceastha		else
1247*3781Sceastha			echo "${2}.gz"
1248*3781Sceastha		fi
1249*3781Sceastha		return 0
1250*3781Sceastha	fi
1251*3781Sceastha}
1252*3781Sceastha
1253*3781Sceastha#
1254*3781Sceastha# $1	- Directory mode
1255*3781Sceastha# $2	- Directory owner (i.e., root:lp)
1256*3781Sceastha# $3	- Directory to create
1257*3781Sceastha#
1258*3781Sceasthamake_dir()
1259*3781Sceastha{
1260*3781Sceastha	if debugger "make_dir" ; then
1261*3781Sceastha		set -x
1262*3781Sceastha	fi
1263*3781Sceastha
1264*3781Sceastha	[[ ! -d "${3}" ]] || return 0
1265*3781Sceastha	/bin/mkdir "${3}" >/dev/null 2>&1 || return 1
1266*3781Sceastha	set_perms ${1} ${2} "${3}"
1267*3781Sceastha	return 0
1268*3781Sceastha}
1269*3781Sceastha
1270*3781Sceastha#
1271*3781Sceastha# Remove a ppdmgr generated cache (in /var/lp/ppd/cache)
1272*3781Sceastha# if it doesn't have an associated label in the repository.
1273*3781Sceastha#
1274*3781Sceastha# $1	- Full path to label
1275*3781Sceastha# $2	- Cache name
1276*3781Sceastha#
1277*3781Sceastharemove_unassociated_cache()
1278*3781Sceastha{
1279*3781Sceastha	if debugger "remove_unassociated_cache" ; then
1280*3781Sceastha		set -x
1281*3781Sceastha	fi
1282*3781Sceastha
1283*3781Sceastha	if [[ "${1}" != "${UNSET}" ]] ; then
1284*3781Sceastha		if [[ -n "${1}" && ! -d "${1}" ]] ; then
1285*3781Sceastha			#
1286*3781Sceastha			# The label doesn't exist, so delete
1287*3781Sceastha			# the associated cache file.
1288*3781Sceastha			#
1289*3781Sceastha			/bin/rm -f "${VARCACHES}/${2}" >/dev/null 2>&1
1290*3781Sceastha		fi
1291*3781Sceastha	fi
1292*3781Sceastha}
1293*3781Sceastha
1294*3781Sceastha#
1295*3781Sceastha# Sorted copies of cache files for each label in each PPD repository
1296*3781Sceastha# are maintained in /var/lp/ppd/caches/<PPD respository>-<label>.
1297*3781Sceastha# This is done so that changes in delivered cache files can be
1298*3781Sceastha# detected.  If a difference in cache files is detected, or a
1299*3781Sceastha# cache file is either added or removed, then we know that
1300*3781Sceastha# the ppdcache file needs to be updated.
1301*3781Sceastha#
1302*3781Sceastha# Get a list of all cache files and compare against the list
1303*3781Sceastha# of labels in all of the PPD file repositories.  They should
1304*3781Sceastha# be the same.  If there is a label in one of the PPD file
1305*3781Sceastha# repositories that doesn't have an associated cache file, then
1306*3781Sceastha# we don't worry about it now, as that will be resolved when
1307*3781Sceastha# we update the cache for that label.  However, if there is
1308*3781Sceastha# a cache file associated with a label that no longer exists, then
1309*3781Sceastha# remove the cache file.
1310*3781Sceastha#
1311*3781Sceastha# $1	- Full path to repository (or "all")
1312*3781Sceastha# $2	- Label name
1313*3781Sceastha#
1314*3781Sceasthaupdate_cache()
1315*3781Sceastha{
1316*3781Sceastha	if debugger ; then
1317*3781Sceastha		set -x
1318*3781Sceastha	fi
1319*3781Sceastha
1320*3781Sceastha	#
1321*3781Sceastha	# Determine which labels in which PPD repository the
1322*3781Sceastha	# cache file will be updated for.
1323*3781Sceastha	#
1324*3781Sceastha	if [[ "${1}" = "all" ]] ; then
1325*3781Sceastha		rname="${REPOSITORIES}"
1326*3781Sceastha	else
1327*3781Sceastha		rname="${1}"
1328*3781Sceastha	fi
1329*3781Sceastha
1330*3781Sceastha	uc_rc=0
1331*3781Sceastha	for dstreppath in ${rname} ; do
1332*3781Sceastha		labellist=
1333*3781Sceastha		if [[ "${2}" = "all" ]] ; then
1334*3781Sceastha			dstrepname=$(get_rep_name "${dstreppath}")
1335*3781Sceastha			labellist=$(get_rep_label_list "${dstreppath}" \
1336*3781Sceastha			    "${dstrepname}")
1337*3781Sceastha		else
1338*3781Sceastha
1339*3781Sceastha			# Ensure the label exists in the PPD file repository.
1340*3781Sceastha			if [[ -d "${dstreppath}/${2}" ]] ; then
1341*3781Sceastha				labellist="${2}"
1342*3781Sceastha			fi
1343*3781Sceastha		fi
1344*3781Sceastha
1345*3781Sceastha		#
1346*3781Sceastha		# Update the cache for each label in the PPD repository
1347*3781Sceastha		#
1348*3781Sceastha		for dstlabel in ${labellist} ; do
1349*3781Sceastha			ulc_msg=$(update_label_cache "${dstreppath}" \
1350*3781Sceastha			    "${dstrepname}" "${dstlabel}")
1351*3781Sceastha			if [[ $? -ne 0 ]] ; then
1352*3781Sceastha				echo "${ulc_msg}"
1353*3781Sceastha				uc_rc=1
1354*3781Sceastha			fi
1355*3781Sceastha		done
1356*3781Sceastha	done
1357*3781Sceastha
1358*3781Sceastha	# Update the golden cache file.
1359*3781Sceastha	update_golden_cache
1360*3781Sceastha	return ${uc_rc}
1361*3781Sceastha}
1362*3781Sceastha
1363*3781Sceastha# $1	- exit status
1364*3781Sceasthappdmgr_exit()
1365*3781Sceastha{
1366*3781Sceastha	if debugger "ppdmgr_exit" ; then
1367*3781Sceastha		set -x
1368*3781Sceastha	fi
1369*3781Sceastha
1370*3781Sceastha	/bin/rm -rf "${ppdmgrtmpdir}" >/dev/null 2>&1
1371*3781Sceastha	exit ${1}
1372*3781Sceastha}
1373*3781Sceastha
1374*3781Sceastha
1375*3781Sceasthausage()
1376*3781Sceastha{
1377*3781Sceastha	gettext "usage:\n" 1>&2
1378*3781Sceastha	print -n "\t$myprog: " 1>&2
1379*3781Sceastha	gettext "-a <ppd_filename_path> [ -L <label> ]\n" 1>&2
1380*3781Sceastha	gettext "\t\t[ -R <ppd_repository> ] [-w]\n" 1>&2
1381*3781Sceastha	print -n "\t$myprog: " 1>&2
1382*3781Sceastha	# gettext "-g <ppd_filename_path> [ -L <label> ]\n" 1>&2
1383*3781Sceastha	# gettext "\t\t[ -R <ppd_repository> ]\n" 1>&2
1384*3781Sceastha	print -n "\t$myprog: " 1>&2
1385*3781Sceastha	gettext "-r [ -L <label> ] [ -R <ppd_repository> ]\n" 1>&2
1386*3781Sceastha	print -n "\t$myprog: " 1>&2
1387*3781Sceastha	gettext "-u [ -L <label> ] [ -R <ppd_repository> ]\n" 1>&2
1388*3781Sceastha
1389*3781Sceastha	ppdmgr_exit ${FAIL}
1390*3781Sceastha}
1391*3781Sceastha
1392*3781Sceastha##########################################################################
1393*3781Sceastha# main
1394*3781Sceastha##########################################################################
1395*3781Sceastha
1396*3781Sceasthamyprog=$(/bin/basename $0)
1397*3781Sceastha
1398*3781SceasthaSaveIFS="$IFS"
1399*3781SceasthaNoSpaceTabIFS='
1400*3781Sceastha'
1401*3781Sceastha
1402*3781Sceastha# Updatable PPD repository
1403*3781SceasthaVARDIR=/var/lp/ppd
1404*3781Sceastha
1405*3781Sceastha# Delivered PPD respository
1406*3781SceasthaSYSTEMREP=/usr/share/ppd
1407*3781SceasthaADMINREP=/usr/local/share/ppd
1408*3781SceasthaVENDORREP=/opt/share/ppd
1409*3781SceasthaUSERREP=${VARDIR}
1410*3781Sceastha
1411*3781SceasthaRESERVEDREPS="${SYSTEMREP} ${ADMINREP} ${VENDORREP}"
1412*3781SceasthaREPOSITORIES="${USERREP} ${RESERVEDREPS}"
1413*3781SceasthaRESERVEDLABELS="all caches ppdcache manufaliases"
1414*3781Sceastha
1415*3781Sceastha# Deliveries
1416*3781SceasthaSYSTEM=system
1417*3781SceasthaVENDOR=vendor
1418*3781SceasthaADMIN=admin
1419*3781SceasthaUSER=user
1420*3781Sceastha
1421*3781Sceastha# Sytem PPD cache name used by printmgr
1422*3781SceasthaGOLDCACHE=${USERREP}/ppdcache
1423*3781Sceastha
1424*3781Sceastha# Delivered caches directory
1425*3781SceasthaCACHES=caches
1426*3781SceasthaMANUFALIASES=manufaliases
1427*3781Sceastha
1428*3781Sceastha# Updated caches directory
1429*3781SceasthaVARCACHES=${VARDIR}/${CACHES}
1430*3781Sceastha
1431*3781Sceastha# valid PPD file name extensions
1432*3781SceasthaPEXT=ppd
1433*3781SceasthaGEXT=gz
1434*3781SceasthaFILEEXTS=".${PEXT} .${PEXT}.${GEXT}"
1435*3781Sceastha
1436*3781Sceastha# Default modes and owners
1437*3781SceasthaDIRMODE=755
1438*3781SceasthaDIROWNER=root:lp
1439*3781SceasthaADMINOWNER=root:root
1440*3781SceasthaFILEMODE=444
1441*3781SceasthaFILEOWNER=root:lp
1442*3781Sceastha
1443*3781Sceastha# ppdmgr actions
1444*3781SceasthaADD=add
1445*3781SceasthaGENERATEENTRY=generateentry
1446*3781SceasthaUPDATE=update
1447*3781SceasthaREBUILD=rebuild
1448*3781Sceastha
1449*3781SceasthaSUCCESS=0
1450*3781SceasthaFAIL=1
1451*3781SceasthaWARN=2
1452*3781Sceastha
1453*3781SceasthaMAXLABELNAME=256
1454*3781SceasthaGZIP="/bin/gzip -c"
1455*3781SceasthaGZCMP="/bin/gzcmp -s"
1456*3781SceasthaCMP="/bin/cmp -s"
1457*3781SceasthaSPECIALCHARS=":"
1458*3781SceasthaSEP=":"
1459*3781Sceastha
1460*3781Sceasthadebug=0
1461*3781Sceasthawflag=0
1462*3781Sceasthastatus=${SUCCESS}
1463*3781Sceastha
1464*3781SceasthaUNSET=""
1465*3781Sceasthappdlabel=${UNSET}
1466*3781Sceasthappdrepname=${UNSET}
1467*3781Sceasthappdreppath=${UNSET}
1468*3781Sceasthamodmanuf=
1469*3781Sceasthamodel=
1470*3781Sceasthanickn=
1471*3781Sceasthadevidmdl=
1472*3781Sceasthadevidmfg=
1473*3781Sceastha
1474*3781Sceasthappdmgrtmpdir=/tmp/ppdmgr.$$
1475*3781Sceastha/bin/mkdir "${ppdmgrtmpdir}" >/dev/null 2>&1
1476*3781Sceasthaset_perms ${DIRMODE} ${DIROWNER} "${ppdmgrtmpdir}"
1477*3781Sceastha
1478*3781Sceasthaaliasfile=${USERREP}/manufaliases
1479*3781Sceasthatmpfilepath=
1480*3781Sceastha
1481*3781Sceastha
1482*3781SceasthaOPTS=a:g:L:rR:uwZ
1483*3781Sceasthawhile getopts "$OPTS" arg ; do
1484*3781Sceastha	case ${arg} in
1485*3781Sceastha	a)	# add PPD file
1486*3781Sceastha		action=${ADD}
1487*3781Sceastha		origsrcppdpath=${OPTARG}
1488*3781Sceastha		;;
1489*3781Sceastha
1490*3781Sceastha	g)	# create cache entry
1491*3781Sceastha		action=${GENERATEENTRY}
1492*3781Sceastha		origsrcppdpath=${OPTARG}
1493*3781Sceastha		;;
1494*3781Sceastha
1495*3781Sceastha	L)	# PPD label name
1496*3781Sceastha		ppdlabel=${OPTARG}
1497*3781Sceastha		;;
1498*3781Sceastha
1499*3781Sceastha	r)	# rebuild cache
1500*3781Sceastha		action=${REBUILD}
1501*3781Sceastha		;;
1502*3781Sceastha
1503*3781Sceastha	R)	# PPD file repository to use
1504*3781Sceastha		ppdrepname=${OPTARG}
1505*3781Sceastha		;;
1506*3781Sceastha
1507*3781Sceastha	u)	# update cache
1508*3781Sceastha		action=${UPDATE}
1509*3781Sceastha		;;
1510*3781Sceastha
1511*3781Sceastha	w)	# display PPD file path
1512*3781Sceastha		wflag=1
1513*3781Sceastha		;;
1514*3781Sceastha
1515*3781Sceastha	Z)	# debug
1516*3781Sceastha		debug=1
1517*3781Sceastha		;;
1518*3781Sceastha
1519*3781Sceastha	?)
1520*3781Sceastha		usage
1521*3781Sceastha		;;
1522*3781Sceastha	esac
1523*3781Sceasthadone
1524*3781Sceastha
1525*3781Sceasthaif debugger "Main" ; then
1526*3781Sceastha	set -x
1527*3781Sceasthafi
1528*3781Sceastha
1529*3781Sceasthaif [[ $# -lt 1 || -z "${action}" ]] ; then
1530*3781Sceastha	usage
1531*3781Sceasthafi
1532*3781Sceastha
1533*3781Sceastha# ignore wflag unless specified with -a
1534*3781Sceasthaif [[ ${wflag} -eq 1 && "${action}" != ${ADD} ]] ; then
1535*3781Sceastha	wflag=0
1536*3781Sceasthafi
1537*3781Sceastha
1538*3781Sceastha#
1539*3781Sceastha# Ensure the destination PPD repository directory is set
1540*3781Sceastha# to match the specified repository.  If the
1541*3781Sceastha# destination PPD file repository was specified, then
1542*3781Sceastha# it must be one of the following:
1543*3781Sceastha# 	"user"
1544*3781Sceastha#	"admin"
1545*3781Sceastha#	"vendor"
1546*3781Sceastha#	"system"
1547*3781Sceastha#	"all"
1548*3781Sceastha#
1549*3781Sceasthacase "${ppdrepname}" in
1550*3781Sceastha"${SYSTEM}")
1551*3781Sceastha	ppdreppath="${SYSTEMREP}"
1552*3781Sceastha	;;
1553*3781Sceastha"${ADMIN}")
1554*3781Sceastha	ppdreppath="${ADMINREP}"
1555*3781Sceastha	;;
1556*3781Sceastha"${VENDOR}")
1557*3781Sceastha	ppdreppath="${VENDORREP}"
1558*3781Sceastha	;;
1559*3781Sceastha"${USER}")
1560*3781Sceastha	ppdreppath="${USERREP}"
1561*3781Sceastha	;;
1562*3781Sceastha"all")
1563*3781Sceastha	if [[ "${action}" = "${ADD}" || \
1564*3781Sceastha	    "${action}" = "${GENERATEENTRY}" ]] ; then
1565*3781Sceastha		print -n "$myprog: " 1>&2
1566*3781Sceastha		gettext "reserved PPD repository name: " 1>&2
1567*3781Sceastha		gettext "${ppdrepname}\n" 1>&2
1568*3781Sceastha		ppdmgr_exit ${FAIL}
1569*3781Sceastha	fi
1570*3781Sceastha	ppdreppath="all"
1571*3781Sceastha	;;
1572*3781Sceastha"${UNSET}"|"")
1573*3781Sceastha	ppdreppath="${UNSET}"
1574*3781Sceastha	;;
1575*3781Sceastha
1576*3781Sceastha*)
1577*3781Sceastha	print -n "$myprog: " 1>&2
1578*3781Sceastha	gettext "invalid PPD repository name: ${ppdrepname}\n" 1>&2
1579*3781Sceastha	ppdmgr_exit ${FAIL}
1580*3781Sceastha	;;
1581*3781Sceasthaesac
1582*3781Sceastha
1583*3781Sceastha#
1584*3781Sceastha# When a source PPD file's path is from a known repository, the
1585*3781Sceastha# destination repository and desination label are assumed to be the
1586*3781Sceastha# same as the source PPD file's unless a differing repository or label
1587*3781Sceastha# was specified.
1588*3781Sceastha#
1589*3781Sceasthaif [[ "${action}" = "${ADD}" || "${action}" = "${GENERATEENTRY}" ]] ; then
1590*3781Sceastha
1591*3781Sceastha	srcppdpath=$(ppd_pathname "${origsrcppdpath}")
1592*3781Sceastha	ppd_pathname_rc=$?
1593*3781Sceastha	if [[ ${ppd_pathname_rc} -ne 0 ]] ; then
1594*3781Sceastha		print -n "$myprog: " 1>&2
1595*3781Sceastha		gettext "invalid PPD file: ${origsrcppdpath}\n" 1>&2
1596*3781Sceastha		ppdmgr_exit ${ppd_pathname_rc}
1597*3781Sceastha	fi
1598*3781Sceastha
1599*3781Sceastha	# Path cannot contain special characters
1600*3781Sceastha	echo "${srcppdpath}" | /bin/egrep  "${SPECIALCHARS}" >/dev/null
1601*3781Sceastha	if [[ $? -eq 0 ]] ; then
1602*3781Sceastha		print -n "$myprog: " 1>&2
1603*3781Sceastha		gettext "PPD path contains " 1>&2
1604*3781Sceastha		gettext "an invalid character: ${ppd_pathname}\n" 1>&2
1605*3781Sceastha		ppdmgr_exit ${FAIL}
1606*3781Sceastha	fi
1607*3781Sceastha	ppdfname=$(/bin/basename "${origsrcppdpath}")
1608*3781Sceastha
1609*3781Sceastha	#
1610*3781Sceastha	# Check to see if there's any work to be done.  If the source file
1611*3781Sceastha	# is already in the destination repository under the destination
1612*3781Sceastha	# label, then there's nothing left to do.  We exit rather than
1613*3781Sceastha	# going on to do an update on the label in the repository as
1614*3781Sceastha	# it could possible take a long time to update.  If an add was
1615*3781Sceastha	# requested, it could have come from an application, so we want
1616*3781Sceastha	# to return quickly.
1617*3781Sceastha	#
1618*3781Sceastha	if label_path_match "${srcppdpath}" "${ppdreppath}" "${ppdlabel}" ; then
1619*3781Sceastha		if [[ ${wflag} -eq 1 || \
1620*3781Sceastha		    "${action}" = "${GENERATEENTRY}" ]] ; then
1621*3781Sceastha			echo "${srcppdpath}"
1622*3781Sceastha		fi
1623*3781Sceastha		ppdmgr_exit ${SUCCESS}
1624*3781Sceastha	fi
1625*3781Sceasthafi
1626*3781Sceastha
1627*3781Sceasthappdlabel=$(valid_specified_label "${ppdlabel}")
1628*3781Sceasthaif [[ $? -ne 0 ]] ; then
1629*3781Sceastha	ppdmgr_exit ${FAIL}
1630*3781Sceasthafi
1631*3781Sceastha
1632*3781Sceasthaif [[ "${ppdreppath}" = "${UNSET}" ]] ; then
1633*3781Sceastha	ppdreppath="${USERREP}"
1634*3781Sceasthafi
1635*3781Sceastha
1636*3781Sceasthadstrepname=$(get_rep_name "${ppdreppath}")
1637*3781Sceastha
1638*3781Sceasthacase "${action}" in
1639*3781Sceastha"${ADD}")
1640*3781Sceastha	#
1641*3781Sceastha	# Attempt to add the PPD file to the repository under the
1642*3781Sceastha	# specified label.  If any errors occur, final_dst_ppd_path
1643*3781Sceastha	# will contain the error message rather than the path to the
1644*3781Sceastha	# PPD file.
1645*3781Sceastha	#
1646*3781Sceastha	final_dst_ppd_path=$(add_ppd "${srcppdpath}" "${ppdfname}" \
1647*3781Sceastha	    "${ppdreppath}" "${dstrepname}" "${ppdlabel}")
1648*3781Sceastha	add_ppd_rc=$?
1649*3781Sceastha	case ${add_ppd_rc} in
1650*3781Sceastha	0)	#
1651*3781Sceastha		# The PPD file was added.  Update the specified
1652*3781Sceastha		# cache associated with the label if the PPD file
1653*3781Sceastha		# was added successfully and was not a duplicate.
1654*3781Sceastha		# Ensure any changes are also reflected in the
1655*3781Sceastha		# golden cache.
1656*3781Sceastha		#
1657*3781Sceastha		add_ppd_msg=$(update_label_cache "${ppdreppath}" \
1658*3781Sceastha		    "${dstrepname}" "${ppdlabel}")
1659*3781Sceastha		apm_rc=$?
1660*3781Sceastha
1661*3781Sceastha		echo "${add_ppd_msg}" | /bin/grep "${final_dst_ppd_path}"
1662*3781Sceastha		path_in_msg=$?
1663*3781Sceastha
1664*3781Sceastha		#
1665*3781Sceastha		# Only report cache update errors if the file that was
1666*3781Sceastha		# added was one that was reported as not being added
1667*3781Sceastha		# to the cache.  This really should happen as the file
1668*3781Sceastha		# was verified during the add.
1669*3781Sceastha		#
1670*3781Sceastha		if [[ ${apm_rc} -ne 0 && ${path_in_msg} -eq 0 ]] ; then
1671*3781Sceastha			print -n "$myprog: " 1>&2
1672*3781Sceastha			gettext "printer information does not reflect " 1>&2
1673*3781Sceastha			gettext "the\nfollowing PPD file(s):\n" 1>&2
1674*3781Sceastha			print "${add_ppd_msg}" 1>&2
1675*3781Sceastha			status=${FAIL}
1676*3781Sceastha		else
1677*3781Sceastha			update_golden_cache
1678*3781Sceastha
1679*3781Sceastha			#
1680*3781Sceastha			# Display the full path to the added PPD file,
1681*3781Sceastha			# if requested (-w).
1682*3781Sceastha			#
1683*3781Sceastha			if [[ ${wflag} -eq 1 ]] ; then
1684*3781Sceastha				print "${final_dst_ppd_path}"
1685*3781Sceastha			fi
1686*3781Sceastha		fi
1687*3781Sceastha		;;
1688*3781Sceastha
1689*3781Sceastha	1)	# Duplicate copy exists
1690*3781Sceastha		if [[ ${wflag} -eq 1 ]] ; then
1691*3781Sceastha			print "${final_dst_ppd_path}"
1692*3781Sceastha		fi
1693*3781Sceastha		;;
1694*3781Sceastha
1695*3781Sceastha	2)	# Varying copy exists
1696*3781Sceastha		print -n "$myprog: " 1>&2
1697*3781Sceastha		gettext "differing variant of source PPD file " 1>&2
1698*3781Sceastha		gettext "already exists at\n" 1>&2
1699*3781Sceastha		gettext "${final_dst_ppd_path}\n" 1>&2
1700*3781Sceastha		status=${FAIL}
1701*3781Sceastha		;;
1702*3781Sceastha	*)	# The PPD file was not added as a problem occurred.
1703*3781Sceastha		# Display the error message.
1704*3781Sceastha		print -n "$myprog: " 1>&2
1705*3781Sceastha		print "${final_dst_ppd_path}" 1>&2
1706*3781Sceastha		status=${FAIL}
1707*3781Sceastha		;;
1708*3781Sceastha
1709*3781Sceastha	esac
1710*3781Sceastha	;;
1711*3781Sceastha
1712*3781Sceastha"${GENERATEENTRY}")
1713*3781Sceastha	#
1714*3781Sceastha	# Create a cache file entry for the specified PPD file and
1715*3781Sceastha	# display it on standard out.
1716*3781Sceastha	#
1717*3781Sceastha	verify_ppd_file "${srcppdpath}"
1718*3781Sceastha	if [[ $? -eq 0 ]] ; then
1719*3781Sceastha		dstdir="${ppdreppath}/${ppdlabel}/${modmanuf}"
1720*3781Sceastha		final_dst_path="${dstdir}/$(/bin/basename ${srcppdpath})"
1721*3781Sceastha		verify_ppd_location "${final_dst_path}"
1722*3781Sceastha		if [[ $? -eq 0 ]] ; then
1723*3781Sceastha			# Generate the cache file entry
1724*3781Sceastha			print "$(generate_cache_file_entry "${modmanuf}" \
1725*3781Sceastha			    "${model}" "${nickn}" "${devidmfg}" "${devidmdl}" \
1726*3781Sceastha			    "${final_dst_path}")"
1727*3781Sceastha		else
1728*3781Sceastha			print -n "$myprog: " 1>&2
1729*3781Sceastha			gettext "PPD file not in valid location\n" 1>&2
1730*3781Sceastha			gettext \
1731*3781Sceastha	    "(<repository>/<label>/<manufacturer>/<PPD file>):\n\t${1}\n" 1>&2
1732*3781Sceastha			status=${FAIL}
1733*3781Sceastha		fi
1734*3781Sceastha
1735*3781Sceastha	else
1736*3781Sceastha		print -n "$myprog: " 1>&2
1737*3781Sceastha		gettext "invalid PPD file: ${1}\n" 1>&2
1738*3781Sceastha		status=${FAIL}
1739*3781Sceastha	fi
1740*3781Sceastha	;;
1741*3781Sceastha
1742*3781Sceastha"${REBUILD}" | "${UPDATE}")
1743*3781Sceastha	update_msg=$(update_cache "${ppdreppath}" "${ppdlabel}")
1744*3781Sceastha	if [[ $? -ne 0 ]] ; then
1745*3781Sceastha		print -n "$myprog: " 1>&2
1746*3781Sceastha		gettext "printer information does not reflect " 1>&2
1747*3781Sceastha		gettext "the\nfollowing PPD file(s):\n" 1>&2
1748*3781Sceastha		print "${update_msg}" 1>&2
1749*3781Sceastha		status=${WARN}
1750*3781Sceastha	fi
1751*3781Sceastha	;;
1752*3781Sceastha
1753*3781Sceastha*)
1754*3781Sceastha	usage
1755*3781Sceastha	;;
1756*3781Sceasthaesac
1757*3781Sceastha
1758*3781Sceasthappdmgr_exit ${status}
1759