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