diff options
Diffstat (limited to 'usr/src/cmd/print/scripts/ppdmgr')
-rw-r--r-- | usr/src/cmd/print/scripts/ppdmgr | 1765 |
1 files changed, 0 insertions, 1765 deletions
diff --git a/usr/src/cmd/print/scripts/ppdmgr b/usr/src/cmd/print/scripts/ppdmgr deleted file mode 100644 index 335c01da7d..0000000000 --- a/usr/src/cmd/print/scripts/ppdmgr +++ /dev/null @@ -1,1765 +0,0 @@ -#!/bin/ksh -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -# -# Description: Script to generate the Solaris printmgr 'ppdcache' file from the -# ppd files installed in the given ppd database directory -# -# ppdmgr -a <ppd_filename_path> [ -L <label> ] [-w] -# ppdmgr -g <ppd_filename_path> [ -L <label> ] [ -R <ppd_repository> ] -# ppdmgr -r [ -L <label> ] [ -R <ppd_repository> ] -# ppdmgr -u [ -L <label> ] [ -R <ppd_repository> ] -# -# Options: -# -a <ppd_filename_path> - Add a new PPD file to the specified -# label in the "user" repository, and -# updates to the "user" repository -# in the ppdcache. -# -g <ppd_filename_path> - Generate a cache file entry -# for the specified PPD file -# on standard out. -# -L <label> - Label name. <label> -# can be any characters from the -# portable character set, however -# may not contain a semi-colon (':'). -# The following are the defaults -# for <label> for each option: -# OPTION DEFAULT LABEL -# ------ ------------- -# -a <label> from <ppd_filename_path> -# if <ppd_filename_path> -# is from a known repository, -# otherwise defaults to "user". -# -g <label> from <ppd_filename_path> -# if <ppd_filename_path> -# is from a known repository, -# otherwise defaults to "user". -# -r all -# -u all -# The following are reserved labels: -# caches - may never be specified -# ppdcache - may never be specified -# manufaliases - may never be specified -# all - applies specified -# action to all labels -# in a repository. -# Can only be specified -# with -r or -u. -# SUNW* - anything starting with -# SUNW is reserved for -# use by Sun, but not -# prohibited. -# -r - Rebuild the cache information for the -# specified label in the specified -# repository. Similar to -u, however, -# the cache file is removed to force an -# update to the ppdcache. -# -R <ppd_repository> - PPD repository name. -# Defaults to "user". -# The following are the possible -# values for <ppd_repository> and -# location in the system: -# REP LOCATION -# --- -------- -# user /var/lp/ppd -# admin /usr/local/share/ppd -# vendor /opt/share/ppd -# system /usr/share/ppd -# all all repositories -# -# Note: When specified with the -a option -# only "user" and "admin" are valid. -# "vendor", "system", and "all" will be -# considered reserved. -# -u - Update the PPD cache information -# for the specified label in the specified -# repository if needed. If the cache -# update was required, then the updated -# cache information is reflected in -# the ppdcache. -# -w - Display full path of where the -# ppd file is located on the system. -# Only valid with -a, otherwise the -# option is ignored. -# -# If -a, -g, -r, or -u are specified on the command line, only the last action -# specified will be performed. -# -# Cache file entry format: -# <ModifiedManufacturerName>:<Model>:<NickName>:<1284DeviceIDManufacturer>:<1284DeviceIDModel>:<FullPPDFilePath> -# HP:HP DeskJet 450:Foomatic/hpijs (recommended):dj450:hp:/usr/share/ppd/HP/HP-DeskJet_450-hpijs.ppd.gz -# - -PATH=/bin:/usr/bin:/usr/sbin export PATH -set -o noclobber - -TEXTDOMAIN="SUNW_OST_OSCMD" -export TEXTDOMAIN - -# -# Generates debug output for calling routine. -# If calling routine's name is passed in, then -# will also generate the name of the calling routine. -# -# $1 - Name of calling routine -debugger() -{ - [[ ${debug} -eq 1 ]] || return 1 - if [[ -n "${1}" ]] ; then - echo "In ${1}..." 1>&2 - fi - return 0 -} - -# -# Set the ownership and permissions on a file. -# -# $1 - Mode -# $2 - Owner:Group -# $3 - Full path to file -# -set_perms() -{ - /bin/chmod -f ${1} "${3}" >/dev/null 2>&1 - /bin/chown -f ${2} "${3}" >/dev/null 2>&1 -} - -# -# Create administrator repository directories, /usr/local/share/ppd, -# if needed. This is a special case a Solaris doesn't deliver -# /usr/local/share and it has different permissions than the -# user repository. -# -# $1 - destination repository name -# -create_adminrep_dirs() -{ - if debugger "check_adminrep_dirs" ; then - set -x - fi - - # Only create administrator repository directories, if needed. - [[ "${1}" = "${ADMIN}" ]] || return 0 - - # Check /usr/local/share/ppd - [[ ! -d "${ADMINREP}" ]] || return 0 - - # Check /usr/local/share - admpar=$(/bin/dirname "${ADMINREP}") - if [[ ! -d "${admpar}" ]] ; then - - # Check /usr/local - admppar=$(/bin/dirname "${admpar}") - if [[ ! -d "${admppar}" ]] ; then - make_dir ${DIRMODE} ${ADMINOWNER} "${admppar}" || \ - return 1 - fi - make_dir ${DIRMODE} ${ADMINOWNER} "${admpar}" || return 1 - fi - make_dir ${DIRMODE} ${ADMINOWNER} ${ADMINREP} || return 1 - return 0 -} - -# -# Returns full path to PPD file that was added to the system. -# -# $1 - Full path to source PPD file -# $2 - PPD file name -# $3 - Full path to repository -# $4 - Repository name -# $5 - Label name -# -# Return codes: -# 0 - File successfully added -# 1 - Error -# 2 - Duplicate file already exists -# -add_ppd() -{ - if debugger ; then - set -x - fi - - verify_ppd_file "${1}" - if [[ $? -ne 0 ]] ; then - gettext "invalid PPD file: ${1}" 2>/dev/null - return 3 - fi - - # The destination path can now be set - dstlabelpath="${3}/${5}" - dstmanufpath="${dstlabelpath}/${modmanuf}" - dstpath="${dstmanufpath}/${2}" - - # - # If a version (either compressed or not compressed) of the PPD - # file exists in the destination in the label/repository, - # then just return as there no work to be done. - dst_copy_path=$(variant_copy "${1}" "${dstpath}" "${6}" "${ppdfname}") - ap_rc=$? - if [[ ${ap_rc} -ne 0 ]] ; then - echo "${dst_copy_path}" - return ${ap_rc} - fi - - # - # Can only add a PPD file to the "user" or "admin" repository. - # Note: this check is here instead of at the top of this - # function as we don't want to cause an error if a user - # specifies the same repository and label as a the specified - # ppd file and the repository of the specified ppd file - # exists in a known repository. - # - if [[ "${4}" != "${USER}" && "${4}" != "${ADMIN}" ]] ; then - gettext "invalid PPD file repository name: ${4}" 2>/dev/null - return 3 - fi - - # Ensure destination directories exist - if ! create_adminrep_dirs ${4} ${DIRMODE} ${ADMINOWNER} || \ - ! make_dir ${DIRMODE} ${DIROWNER} "${3}" || \ - ! make_dir ${DIRMODE} ${DIROWNER} "${dstlabelpath}" || \ - ! make_dir ${DIRMODE} ${DIROWNER} "${dstmanufpath}" ; then - gettext "unable to create destination directories" 2>/dev/null - return 3 - fi - - # Copy source PPD file, and compress if needed, to destination - if [[ "${ppdfileext}" = "${PEXT}" ]] ; then - ${GZIP} "${1}" >"${dst_copy_path}" 2>/dev/null - if [[ $? -eq 1 ]] ; then - gettext "unable to copy PPD file " 2>/dev/null - gettext "to destination" 2>/dev/null - return 3 - fi - else - /bin/cp -f "${1}" "${dst_copy_path}" >/dev/null 2>&1 - if [[ $? -ne 0 ]] ; then - gettext "unable to copy PPD file " 2>/dev/null - gettext "to destination" 2>/dev/null - return 3 - fi - fi - set_perms ${FILEMODE} ${FILEOWNER} "${dst_copy_path}" - - echo "${dst_copy_path}" - - return 0 -} - -# -# Returns 0 if the cache needs to be modified, otherwise -# returns 1. -# -# $1 - Full path to cache -# $2 - Full path to cache replacement candidate -# -changes_in_cache() -{ - if debugger "changes_in_cache" ; then - set -x - fi - - if [[ "${action}" = "${REBUILD}" ]] ; then - return 0 - fi - [[ "${2}" -nt "${1}" ]] || return 1 - if $(${CMP} "${1}" "${2}" >/dev/null 2>&1) ; then - # No differences. Just update timestamp - /bin/touch -r "${2}" "${1}" >/dev/null 2>&1 - return 1 - else - return 0 - fi -} - -# -# Generate a new golden cache file (/var/lp/ppd/ppdcache), by -# concatenating and sorting all existing cache files in /var/lp/ppd/caches. -# -# If there are difference between the newly generated golden cache file and -# the existing one (if it exists) then the newly generated one replaces the -# existing one at /var/lp/ppd/ppdcache. -# -update_golden_cache() -{ - - if debugger "update_golden_cache" ; then - set -x - fi - - # - # Remove any cache files that don't have an associated - # label. - # - for cname in $(/bin/ls ${VARCACHES} 2>/dev/null) ; do - repname="${cname%%:*}" - cfile="${cname#*:}" - checkdir="$(get_rep_path ${repname})/${cfile}" - remove_unassociated_cache "${checkdir}" "${cname}" - done - - # - # Combine the contents of all cache files into a - # temporary golden cache file. - # - tmpgoldencache=$ppdmgrtmpdir/tmpgoldencache - - /bin/sort "${VARCACHES}"/* >>"${tmpgoldencache}" 2>/dev/null - - if [[ ! -s "${tmpgoldencache}" ]] ; then - # No cache files. Remove golden cache. - /bin/rm -f "${GOLDCACHE}" >/dev/null 2>&1 - /bin/rm -f "${tmpgoldencache}" >/dev/null 2>&1 - elif [[ -e "${GOLDCACHE}" ]] ; then - # - # Use the newly generated "temporary" golden cache file if there - # differences between the current and newly generated ppdcache - # or if a rebuild is being performed. - # - if [[ "${VARCACHES}" -nt "${GOLDCACHE}" ]] || \ - changes_in_cache "${GOLDCACHE}" "${tmpgoldencache}" ; then - set_perms ${FILEMODE} ${FILEOWNER} "${tmpgoldencache}" - /bin/mv -f "${tmpgoldencache}" \ - "${GOLDCACHE}" >/dev/null 2>&1 - else - /bin/rm -f "${tmpgoldencache}" >/dev/null 2>&1 - fi - else - # There wasn't an existing ppdcache. Install the newly - # generated ppdcache file to the golden ppdcache. - set_perms ${FILEMODE} ${FILEOWNER} "${tmpgoldencache}" - /bin/mv -f "${tmpgoldencache}" "${GOLDCACHE}" >/dev/null 2>&1 - fi -} - -# -# Returns a list of PPD files that exist. -# -# $1 - Full path to cache file -# -remove_invalid_cache_entries() -{ - if debugger ; then - set -x - fi - - [[ -s "${1}" ]] || return - - IFS="$NoSpaceTabIFS" - for centry in $(/bin/cat "${1}" 2>/dev/null) ; do - IFS="$SaveIFS" - # - # Keep the entry from the ppd cache if it still - # exists and there haven't been any modifications - # since the last update to the cache. - # - if [[ -n "${centry}" ]] ; then - ppdfile="${centry##*:}" - if [[ -n "${ppdfile}" && -e "${ppdfile}" && - "${1}" -nt "${ppdfile}" ]] ; then - echo "${centry}" - fi - fi - IFS="$NoSpaceTabIFS" - done - IFS="$SaveIFS" -} - -# -# Returns 0 if the path to the PPD is as follows: -# <PPD file repository>/<label>/<manufacturer>/<PPD file> -# otherwise, returns 1 -# -# $1 Full path to PPD file -# -verify_ppd_location() -{ - if debugger ; then - set -x - fi - - # - # Strip off what should be <label>/<manufacturer>/<PPD file> - # and verify the PPD file repository matches one of the - # known PPD file repositories. - # - ppd_file_repository=${1%/*/*/*} - found=1 - for repository in ${REPOSITORIES} ; do - if [[ "${repository}" = "${ppd_file_repository}" ]] ; then - found=0 - break - fi - done - return ${found} -} - -# -# Generate, and sort, cache entries for each PPD files in the specified -# list to the specified file. -# -# $1 - List of full paths to PPD files -# $2 - Full path to current cache file -# $3 - Full path to label -# $4 - Full path to new cache file to generate -# -# Return code: -# 0 success -# 1 unsuccessful -# -generate_label_cache_file() -{ - if debugger ; then - set -x - fi - - # - # Generate a cache file containing cache entries for - # all files in the label. - # - ucfile=$ppdmgrtmpdir/unsortedcache - - # - # Before processing new files, remove any cache entries - # which may be invalid. - # - valid_files= - if [[ -e "${2}" && "${action}" != "${REBUILD}" ]] ; then - valid_files=$(remove_invalid_cache_entries "${2}") - if [[ -n "${valid_files}" ]] ; then - echo "${valid_files}" >>${ucfile} - fi - fi - - # - # If there are no valid PPD files in the current cache file, - # and there are no new PPD files to process, the only thing - # left to do is to remove the current cache file. - # - if [[ -z "${valid_files}" && -z "${1}" ]] ; then - /bin/rm -f "${2}" >/dev/null 2>&1 - /bin/rm -f "${ucfile}" >/dev/null 2>&1 - return 0 - fi - - # - # For each of the label's PPD files, generate - # a cache file entry and add it to the cache file. - # - vpl_rc=0 - vpf_rc=0 - vpl_msg= - vpf_msg= - IFS="$NoSpaceTabIFS" - for fname in ${1} ; do - IFS="$SaveIFS" - if [[ -n "${fname}" ]] ; then - verify_ppd_location "${fname}" - vpl_rc=$? - if [[ ${vpl_rc} -ne 0 ]] ; then - vpl_msg="${vpl_msg}\t${fname}\n" - fi - - verify_ppd_file "${fname}" - vpf_rc=$? - if [[ ${vpf_rc} -ne 0 ]] ; then - vpf_msg="${vpf_msg}\t${fname}\n" - fi - - if [[ ${vpl_rc} -eq 0 && ${vpf_rc} -eq 0 ]] ; then - echo "$(generate_cache_file_entry \ - "${modmanuf}" "${model}" "${nickn}" \ - "${devidmfg}" "${devidmdl}" "${fname}")" - fi - fi - IFS="$NoSpaceTabIFS" - done >>"${ucfile}" - IFS="$SaveIFS" - /bin/sort -u "${ucfile}" >>"${4}" 2>/dev/null - /bin/rm -f "${ucfile}" >/dev/null 2>&1 - - [[ -n "${vpl_msg}" || -n "${vpf_msg}" ]] || return 0 - if [[ -n ${vpl_msg} ]] ; then - gettext " PPD file(s) not in valid location\n" 2>/dev/null - gettext \ - " (<repository>/<label>/<manufacturer>/<PPD file>):\n" 2>/dev/null - echo "${vpl_msg}" - fi - if [[ -n ${vpf_msg} ]] ; then - gettext " invalid PPD file(s):\n" 2>/dev/null - echo "${vpf_msg}" - fi - return 1 -} - -# -# Update current cache file with candidate cache file if there are -# differences. -# -# $1 - Current cache file -# $2 - Candidate cache file to update -# $3 - Repository name -# -update_current_cache_file() -{ - if debugger "update_current_cache_file" ; then - set -x - fi - - if [[ ! -s "${2}" ]] ; then - # - # Candidate cache has zero size (label - # directory with no PPD files under it). - # Delete the empty candidate cache - # file and delete the current cache - # file. - # - /bin/rm -f "${1}" >/dev/null 2>&1 - /bin/rm -f "${2}" >/dev/null 2>&1 - elif [[ -e "${1}" ]] ; then - # - # If there are differences between the current - # cache file and the newly generated one, then - # replace the current one with the new one, and - # set the flag to update the golden ppdcache - # file. - # - if changes_in_cache "${1}" "${2}" ; then - set_perms ${FILEMODE} ${FILEOWNER} "${2}" - /bin/mv -f "${2}" "${1}" >/dev/null 2>&1 - else - /bin/rm -f "${2}" >/dev/null 2>&1 - fi - else - - # - # There is no current cache file. Move the candidate - # to the caches directory. - # - set_perms ${FILEMODE} ${FILEOWNER} "${2}" - /bin/mv -f "${2}" "${1}" >/dev/null 2>&1 - fi -} - -# -# Returns 0 if there are files in $1 with newer timestamp -# than $2 or if deletions have occurred under $1, -# otherwise returns 1. -# -# $1 - Full path to the destination label -# $2 - Full path to label cache file -# -changes_under_label() -{ - if debugger ; then - set -x - fi - - # First check for newer files in the directory - if [[ -e "${2}" && "${action}" != "${REBUILD}" ]] ; then - newfiles=$(/bin/find "${1}" -type f -newer "${2}") - else - newfiles=$(/bin/find "${1}" -type f) - fi - echo "${newfiles}" - [[ -z "${newfiles}" ]] || return 0 - - # - # Need to detect if PPD files have been deleted by checking - # timestamps on label and manufacturer directories. - # - [[ ! "${1}" -nt "${2}" ]] || return 0 - /bin/find "${1}" -type d -newer "${2}" >/dev/null 2>&1 || return 1 - return 0 -} - -# -# If -R was specified, or the timestamp on the specified label's -# directory or any of the PPD files under the specified label in -# the specified PPD file respository is newer than the cache file -# associated with the label, then generate a new sorted cache file. -# -# The new cache will replace the existing one (if any) only if there -# are differences. Note: if -r was specified, then a new cache file -# file will always be installed at -# /var/lp/ppd/caches/<PPD file repository name>-<label name> -# -# $1 - Full path of the destination PPD file repository -# $2 - Destination PPD file repository name -# $3 - Destination label name -# -update_label_cache() -{ - if debugger ; then - set -x - fi - - dstlabelpath="${1}/${3}" - replabelcachepath="${1}/${CACHES}/${3}" - varlabelcachepath="${VARCACHES}/${2}${SEP}${3}" - - ulc_rc=0 - if [[ -d "${dstlabelpath}" ]] ; then - - # - # If the cache doesn't exist for a label, - # or if there were any changes under a label - # (i.e., the timestamp on the label directory or any - # of the PPD files under it is newer than the - # existing cache file), then generate a new cache file. - # - tmpcachepath=$ppdmgrtmpdir/tmpcachepath - - # if this is a system repository, check for a prepopulated cache - if [[ "${2}" = "${SYSTEM}" && -e ${FOOCACHEDIR}/${3}.cache ]] ; then - # copy prepopulated cache - /bin/cp -f ${FOOCACHEDIR}/${3}.cache ${tmpcachepath} - - else - newfileslist=$(changes_under_label "${dstlabelpath}" \ - "${varlabelcachepath}") - if [[ $? -eq 0 ]] ; then - err_files=$(generate_label_cache_file \ - "${newfileslist}" "${varlabelcachepath}" \ - "${dstlabelpath}" "${tmpcachepath}") - if [[ $? -ne 0 ]] ; then - # - # At least one PPD file was invalid. - # Don't return yet, as the cache info - # for the valid PPD files can still be - # used to generate a cache file. - # - echo "${err_files}" - ulc_rc=1 - fi - fi - fi - - if [[ -e "${tmpcachepath}" ]] ; then - update_current_cache_file \ - "${varlabelcachepath}" "${tmpcachepath}" "${2}" - /bin/rm -f "${tmpcachepath}" >/dev/null 2>&1 - fi - else - # - # If there is a cache file in /var/lp/ppd/caches associated - # with the label which no longer exists, remove it. - # - /bin/rm -f "${varlabelcachepath}" >/dev/null 2>&1 - fi - return ${ulc_rc} -} - -# -# Returns the alias for the specified real manufacturer's name. -# -# $1 - Real manufacturer's name -# $2 - File containing list of files that have manufacturers aliases -# -manuf_name_alias() -{ - if debugger ; then - set -x - fi - - # - # Found a couple of PPD files which had special characters - # in the Manufacturer name (i.e, the following is the Manufacturer - # entry: - # *Manufacturer: "Canon Inc. (Kosugi Offic" - # We'll only search the alias file for "Canon Inc." - # - tmpmanuf="${1% *\(*}" - - # Search alias files for a match on the real manufacturer name - if [[ -s "${2}" ]] ; then - # - # Check the manufacturer aliases file for case - # insensitive match of the Manufacturer entry - # from the PPD file. If a match is found, - # then modify the manufacturer entry to - # be that of the specified alias. - # - manufaliases=$(/bin/egrep -i \ - "^${tmpmanuf}:|:${tmpmanuf}:|:${tmpmanuf}$" "${2}") - if [[ -n "${manufaliases}" ]] ; then - echo "${manufaliases%%:*}" - break - else - echo "${tmpmanuf}" - fi - else - echo "${tmpmanuf}" - fi -} - -# -# Returns 0 if the extension to the specified PPD file is a known -# extension, otherwise returns 1. -# -# $1 - Full path to PPD file -# -# Set upon return: -# ppdfileext - PPD file ext (.ppd or .ppd.gz) -# -verify_file_ext() -{ - if debugger ; then - set -x - fi - - if [[ "${1%.gz}".gz = "${1}" ]] ; then - ppdfileext=${GEXT} - elif [[ "${1%.ppd}".ppd = "${1}" ]] ; then - ppdfileext=${PEXT} - else - # invalid PPD file name extension - return 1 - fi - - return 0 -} - -# -# Return the lines from the specified PPD file matching the specified -# spec items. -# -# $1 - spec entries from PPD file -# $2 - spec item -# -# $1 example - 1 string with substrings separated by newline: -# *PPD-Adobe: "4.3" -# *Manufacturer: "HP" -# *Product: "(officejet 4200 series)" -# *ModelName: "HP OfficeJet 4200" -# *NickName: "HP OfficeJet 4200 Foomatic/hpijs (recommended)" -# $2 example: -# ^\*Manufacturer -# -spec_entry() -{ - if debugger ; then - set -x - fi - - item=$(echo "${1}" | /bin/grep ${2}) - # Remove everything up to and including the first quote - item=${item#*\"} - # Remove the end quote - echo "${item%\"}" -} - -# -# Return the lines from the specified PPD file matching the specified -# spec items. -# -# Note: this is similar to spec_entry() except the tokens in the -# spec entry are different. -# -# $1 - spec entries from PPD file -# $2 - spec item -# -devid_spec_entry() -{ - if debugger ; then - set -x - fi - - item=$(echo "${1}" | /bin/grep ${2}) - # Remove everything up to and including the first semi-colon - item=${item#*\:} - # Remove the end quote - echo ${item%\;} - -} - -# -# Verifies that the specified PPD file -# - has a valid extension -# - has the following required spec file entries: -# *PPD-Adobe: "4.3" -# Manufacturer -# Product -# ModelName -# NickName -# -# In addition, the manufacture and model from the IEEE1284 device id -# information will be gathered here, although it's not an error that -# it isn't in the PPD file as many don't contain the IEEE1284 info. -# -# $1 - Full path to PPD file -# -# Return codes: -# 0 success -# 1 invalid PPD file -# -verify_ppd_file() -{ - if debugger ; then - set -x - fi - - ADOBESPEC="PPD-Adobe" - MANUF="Manufacturer" - PRODUCT="Product" - MODEL="ModelName" - NICKNAME="NickName" - DEVID="1284DeviceID" - - # Verify the PPD file extension - verify_file_ext "${1}" || return 1 - - # Query for the required spec items - searchentries="^\*${ADOBESPEC}:|^\*${MANUF}:|^\*${PRODUCT}:" - searchentries="${searchentries}|^\*${MODEL}:|^\*${NICKNAME}:" - searchentries="${searchentries}|^\*${DEVID}:" - ppd_info="$(/bin/gzgrep -e "${searchentries}" "${1}")" - - # - # Process the query results to verify each of the required spec - # file items appears in the PPD file. - # - for spec_item in ${ADOBESPEC} ${MANUF} ${PRODUCT} ${MODEL} \ - ${NICKNAME} ; do - entry=$(spec_entry "${ppd_info}" "^\*${spec_item}:") - [[ ! -z "${entry}" ]] || return 1 - case ${spec_item} in - ${MANUF}) - realmanuf="${entry}" - ;; - ${PRODUCT}) - product="${entry}" - ;; - ${MODEL}) - model="${entry}" - ;; - ${NICKNAME}) - # - # Remove the model and any commas and spaces - # which appear before the driver - # - nickn="${entry#$model[, ]*}" - ;; - esac - - done - - # Save IEEE1284 device id information - if $(echo "${ppd_info}" | grep "${DEVID}" >/dev/null 2>&1) ; then - DMDL="MDL" - DMFG="MFG" - devid="$(/bin/gzgrep -e "^[ ]*${DMDL}:|^[ ]*${DMFG}:" "${1}")" - devidmdl="$(devid_spec_entry "${devid}" "${DMDL}")" - devidmfg="$(devid_spec_entry "${devid}" "${DMFG}")" - else - devidmdl= - devidmfg= - fi - modmanuf=$(manuf_name_alias "${realmanuf}" ${aliasfile}) - - return 0 -} - -# -# generate_cache_file_entry() -# -# Returns a cache file entry for the specified PPD file. -# -# $1 - modmanuf -# $2 - model -# $3 - nickn -# $4 - devidmfg -# $5 - devidmdl -# $6 - Full path to the specified PPD file -# -generate_cache_file_entry() -{ - if debugger "generate_cache_file_entry" ; then - set -x - fi - - echo "${1}":"${2}":"${3}":"${4}":"${5}":"${6}" -} - -# -# Expand specified file to the full path. -# -# $1 - File path to expand -# -# Return code set to 0 if expanded successfully, otherwise set to 1. -# -ppd_pathname() -{ - if debugger ; then - set -x - fi - - if [[ -f "${1}" && -s "${1}" ]] ; then - (cd "$(/bin/dirname "${1}")" ; \ - echo "$(/bin/pwd)/$(/bin/basename "${1}")") || return 1 - return 0 - else - return 1 - fi -} - -# -# Returns the PPD repsitory path associated with the specified -# PPD repository name. -# -# $1 - Repository name -# -get_rep_path() -{ - if debugger ; then - set -x - fi - - case ${1} in - ${SYSTEM}) - echo "${SYSTEMREP}" - ;; - ${VENDOR}) - echo "${VENDORREP}" - ;; - ${ADMIN}) - echo "${ADMINREP}" - ;; - ${USER}) - echo "${USERREP}" - ;; - *) - echo "${UNSET}" - ;; - esac -} - -# -# Returns the PPD respository name from the repository path -# -# $1 - PPD repository path -# -get_rep_name() -{ - if debugger ; then - set -x - fi - - case ${1} in - ${SYSTEMREP}) - echo "${SYSTEM}" - ;; - ${VENDORREP}) - echo "${VENDOR}" - ;; - ${ADMINREP}) - echo "${ADMIN}" - ;; - ${USERREP}) - echo "${USER}" - ;; - "all") - echo "all" - ;; - *) - echo "${UNSET}" - ;; - esac -} - -# -# Returns 0 if a matching label name is found in the specified repository, -# otherwise returns 1. -# -# $1 - repository path -# $2 - label name -# -label_path_in_repository() -{ - if debugger "label_path_in_repository" ; then - set -x - fi - - [[ "${1}" != "" && "${2}" != "" ]] || return 1 - lpir_rc=1 - for repository in ${REPOSITORIES} ; do - if [[ "${repository}" = "${1}" && -d "${1}/${2}" ]] ; then - lpir_rc=0 - break - fi - done - return ${lpir_rc} -} - -# -# Returns 0 if the source label path is the same -# as the destination label path, otherwise returns 1. -# -# $1 - full path to source PPD file (source label path) -# $2 - destination repository path -# $3 - destination label name -# -label_path_match() -{ - if debugger "label_path_match" ; then - set -x - fi - - # dest repository not specified - if [[ "${2}" = "${UNSET}" ]] ; then - # dest label not specified - if [[ "${3}" = "${UNSET}" ]] ; then - # - # We've found a match if the label path is in a known - # repository. - # - lpath="${1%/*/*}" - label_path_in_repository \ - "${1%/*/*/*}" "${lpath##*/}" || return 1 - else - # - # If the source label path exists in the - # in a known repository, and the destination - # label is the same as the source label, - # then we'll assume the default destination - # repository is the same as the source - # destination repository. - # - [[ "${1%/*/*}" = "${1%/*/*/*}/${3}" ]] || return 1 - label_path_in_repository "${1%/*/*/*}" "${3}" || \ - return 1 - fi - - # dest repository specified, dest label not specified - elif [[ "${3}" = "${UNSET}" ]] ; then - # - # If the destination repository path is the same as the - # source repository, and if the source label exists in the - # destination repository path, then we'll assume the default - # destination label is the same as the source label. - # - [[ "${2}" = "${1%/*/*/*}" ]] || return 1 - lpath="${1%/*/*}" - label_path_in_repository "${2}" "${lpath##*/}" || return 1 - - # dest repository and dest label specified. - else - # - # We've found a match if the destination and label - # match those of the source label path, and the source - # label path is in a known repository. - # - [[ "${1%/*/*}" = "${2}/${3}" ]] || return 1 - label_path_in_repository "${2}" "${3}" || return 1 - fi - return 0 -} - -# -# Returns 0 if specified label name is a reserved label, otherwise -# returns 1. -# -# $1 - label name -# -reserved_label() -{ - if debugger ; then - set -x - fi - - rl_rc=1 - for labelname in ${RESERVEDLABELS} ; do - if [[ "${1}" = "${labelname}" ]] ; then - rl_rc=0 - break - fi - done - return ${rl_rc} -} - -# -# Returns a list of all labels that exist in a repository that are -# not reserved labels. -# -# $1 - Full path of repository -# $2 - Repository name -# -get_rep_label_list() -{ - if debugger ; then - set -x - fi - - # - # Get a list of all labels that exist in all of the - # PPD file repository. - # - for lname in $(/bin/ls "${1}" 2>/dev/null) ; do - if [[ -d "${1}/${lname}" ]] ; then - if ! reserved_label "${lname}" ; then - echo "${lname} " - fi - fi - done -} - -# -# Returns a valid PPD label. -# -# Verifies the specified PPD label is a valid label. If the -# label is not set, then it is set to a default value. -# -# Return code set to 0 if the specified PPD label is valid, otherwise 1. -# -# $1 - PPD label -# -valid_specified_label() -{ - if debugger ; then - set -x - fi - - # Verify the specified label - vsl_rc=0 - case "${1}" in - "all") - # Reserved label name with -a or -g options - if [[ "${action}" = "${ADD}" || \ - "${action}" = "${GENERATEENTRY}" ]] ; then - print -n "$myprog: " 1>&2 - gettext "reserved PPD label name: ${1}\n" 1>&2 - vsl_rc=1 - else - echo "${1}" - fi - ;; - - "ppdcache" | "caches" | "manufaliases") - # Reserved label names with any option - print -n "$myprog: " 1>&2 - gettext "reserved PPD label name: ${1}\n" 1>&2 - vsl_rc=1 - ;; - - "" | "${UNSET}") - # Label name not specified. Set the default label name. - # For -g and -a, default is "user", otherwise, default - # is "all". - if [[ "${action}" = "${ADD}" || \ - "${action}" = "${GENERATEENTRY}" ]] ; then - echo "${USER}" - else - echo "all" - fi - ;; - - *) - # label cannot be "." or ".." - if [[ "${1}" = "." || "${1}" = ".." ]] ; then - print -n "$myprog: " 1>&2 - gettext "PPD label name cannot be " 1>&2 - gettext "\".\" or \"..\"\n" 1>&2 - vsl_rc=1 - fi - - # Label name cannot contain special characters - echo "${1}" | /bin/egrep "${SPECIALCHARS}" >/dev/null - if [[ $? -eq 0 ]] ; then - print -n "$myprog: " 1>&2 - gettext "PPD label name contains " 1>&2 - gettext "an invalid character: ${1}\n" 1>&2 - vsl_rc=1 - else - echo "${1}" - fi - ;; - esac - return ${vsl_rc} -} - -# -# Returns the full path of any variant copy of the source file in -# the destination label/repository. -# -# $1 - Full path to source PPD file -# $2 - Full path to destination PPD file -# -# Return code set to -# 0 - Copy doesn't exist -# 1 - Duplicate copy exists -# 2 - Variant copy exists -# -variant_copy() -{ - if debugger ; then - set -x - fi - - # - # First make sure there is not a .ppd and a .ppd.gz version - # of the destination file; users should know not to do this. - # - if [[ -e "${2%.gz}" && -e "${2%.gz}.gz" ]] ; then - /bin/rm -f "${2%.gz}" >/dev/null 2>&1 - fi - - # Use gzcmp to compare PPD files as it can deal with - # gzipped or regular files. - if $(${GZCMP} "${1}" "${2}"* >/dev/null 2>&1) ; then - echo "${2}"* - return 1 - elif [[ -e "${2%.gz}" ]] ; then - echo "${2%.gz}" - return 2 - elif [[ -e "${2%.gz}.gz" ]] ; then - echo "${2%.gz}.gz" - return 2 - else - # - # A PPD file doesn't exist in the destination - # repository under the destination label. - # Just display the source PPD file, ensuring - # it has a gzip extension as we will always - # try to gzip the copy in the destination. - # - if [[ "${1#*.ppd}" = ".gz" ]] ; then - echo "${2}" - else - echo "${2}.gz" - fi - return 0 - fi -} - -# -# $1 - Directory mode -# $2 - Directory owner (i.e., root:lp) -# $3 - Directory to create -# -make_dir() -{ - if debugger "make_dir" ; then - set -x - fi - - [[ ! -d "${3}" ]] || return 0 - /bin/mkdir "${3}" >/dev/null 2>&1 || return 1 - set_perms ${1} ${2} "${3}" - return 0 -} - -# -# Remove a ppdmgr generated cache (in /var/lp/ppd/cache) -# if it doesn't have an associated label in the repository. -# -# $1 - Full path to label -# $2 - Cache name -# -remove_unassociated_cache() -{ - if debugger "remove_unassociated_cache" ; then - set -x - fi - - if [[ "${1}" != "${UNSET}" ]] ; then - if [[ -n "${1}" && ! -d "${1}" ]] ; then - # - # The label doesn't exist, so delete - # the associated cache file. - # - /bin/rm -f "${VARCACHES}/${2}" >/dev/null 2>&1 - fi - fi -} - -# -# Sorted copies of cache files for each label in each PPD repository -# are maintained in /var/lp/ppd/caches/<PPD respository>-<label>. -# This is done so that changes in delivered cache files can be -# detected. If a difference in cache files is detected, or a -# cache file is either added or removed, then we know that -# the ppdcache file needs to be updated. -# -# Get a list of all cache files and compare against the list -# of labels in all of the PPD file repositories. They should -# be the same. If there is a label in one of the PPD file -# repositories that doesn't have an associated cache file, then -# we don't worry about it now, as that will be resolved when -# we update the cache for that label. However, if there is -# a cache file associated with a label that no longer exists, then -# remove the cache file. -# -# $1 - Full path to repository (or "all") -# $2 - Label name -# -update_cache() -{ - if debugger ; then - set -x - fi - - # - # Determine which labels in which PPD repository the - # cache file will be updated for. - # - if [[ "${1}" = "all" ]] ; then - rname="${REPOSITORIES}" - else - rname="${1}" - fi - - uc_rc=0 - for dstreppath in ${rname} ; do - labellist= - if [[ "${2}" = "all" ]] ; then - dstrepname=$(get_rep_name "${dstreppath}") - labellist=$(get_rep_label_list "${dstreppath}" \ - "${dstrepname}") - else - - # Ensure the label exists in the PPD file repository. - if [[ -d "${dstreppath}/${2}" ]] ; then - labellist="${2}" - fi - fi - - # - # Update the cache for each label in the PPD repository - # - for dstlabel in ${labellist} ; do - ulc_msg=$(update_label_cache "${dstreppath}" \ - "${dstrepname}" "${dstlabel}") - if [[ $? -ne 0 ]] ; then - echo "${ulc_msg}" - uc_rc=1 - fi - done - done - - # Update the golden cache file. - update_golden_cache - return ${uc_rc} -} - -# $1 - exit status -ppdmgr_exit() -{ - if debugger "ppdmgr_exit" ; then - set -x - fi - - /bin/rm -rf "${ppdmgrtmpdir}" >/dev/null 2>&1 - exit ${1} -} - - -usage() -{ - gettext "usage:\n" 1>&2 - print -n "\t$myprog: " 1>&2 - gettext "-a <ppd_filename_path> [ -L <label> ]\n" 1>&2 - gettext "\t\t[ -R <ppd_repository> ] [-w]\n" 1>&2 - print -n "\t$myprog: " 1>&2 - gettext "-r [ -L <label> ] [ -R <ppd_repository> ]\n" 1>&2 - print -n "\t$myprog: " 1>&2 - gettext "-u [ -L <label> ] [ -R <ppd_repository> ]\n" 1>&2 - - ppdmgr_exit ${FAIL} -} - -########################################################################## -# main -########################################################################## - -myprog=$(/bin/basename $0) - -SaveIFS="$IFS" -NoSpaceTabIFS=' -' - -# Updatable PPD repository -VARDIR=/var/lp/ppd - -# Delivered PPD respository -SYSTEMREP=/usr/share/ppd -ADMINREP=/usr/local/share/ppd -VENDORREP=/opt/share/ppd -USERREP=${VARDIR} - -RESERVEDREPS="${SYSTEMREP} ${ADMINREP} ${VENDORREP}" -REPOSITORIES="${USERREP} ${RESERVEDREPS}" -RESERVEDLABELS="all caches ppdcache manufaliases" - -# Directory where system:SUNWfoomatic is delivered -FOOCACHEDIR=/usr/lib/lp/caches - -# Deliveries -SYSTEM=system -VENDOR=vendor -ADMIN=admin -USER=user - -# Sytem PPD cache name used by printmgr -GOLDCACHE=${USERREP}/ppdcache - -# Delivered caches directory -CACHES=caches -MANUFALIASES=manufaliases - -# Updated caches directory -VARCACHES=${VARDIR}/${CACHES} - -# valid PPD file name extensions -PEXT=ppd -GEXT=gz -FILEEXTS=".${PEXT} .${PEXT}.${GEXT}" - -# Default modes and owners -DIRMODE=755 -DIROWNER=root:lp -ADMINOWNER=root:root -FILEMODE=444 -FILEOWNER=root:lp - -# ppdmgr actions -ADD=add -GENERATEENTRY=generateentry -UPDATE=update -REBUILD=rebuild - -SUCCESS=0 -FAIL=1 -WARN=2 - -MAXLABELNAME=256 -GZIP="/bin/gzip -c" -GZCMP="/bin/gzcmp -s" -CMP="/bin/cmp -s" -SPECIALCHARS=":" -SEP=":" - -debug=0 -wflag=0 -status=${SUCCESS} - -UNSET="" -ppdlabel=${UNSET} -ppdrepname=${UNSET} -ppdreppath=${UNSET} -modmanuf= -model= -nickn= -devidmdl= -devidmfg= - -ppdmgrtmpdir=$(/usr/bin/mktemp -t -d ppdmgr.XXXXXX) -if [ -z "$ppdmgrtmpdir" ] ; then - print -n "$myprog: " 1>&2 - gettext "Fatal error: could not create temporary directory\n" 1>&2 - exit 1 -fi - -aliasfile=${USERREP}/manufaliases -tmpfilepath= - - -OPTS=a:g:L:rR:uwZ -while getopts "$OPTS" arg ; do - case ${arg} in - a) # add PPD file - action=${ADD} - origsrcppdpath=${OPTARG} - ;; - - g) # create cache entry - action=${GENERATEENTRY} - origsrcppdpath=${OPTARG} - ;; - - L) # PPD label name - ppdlabel=${OPTARG} - ;; - - r) # rebuild cache - action=${REBUILD} - ;; - - R) # PPD file repository to use - ppdrepname=${OPTARG} - ;; - - u) # update cache - action=${UPDATE} - ;; - - w) # display PPD file path - wflag=1 - ;; - - Z) # debug - debug=1 - ;; - - ?) - usage - ;; - esac -done - -if debugger "Main" ; then - set -x -fi - -if [[ $# -lt 1 || -z "${action}" ]] ; then - usage -fi - -# ignore wflag unless specified with -a -if [[ ${wflag} -eq 1 && "${action}" != ${ADD} ]] ; then - wflag=0 -fi - -# -# Ensure the destination PPD repository directory is set -# to match the specified repository. If the -# destination PPD file repository was specified, then -# it must be one of the following: -# "user" -# "admin" -# "vendor" -# "system" -# "all" -# -case "${ppdrepname}" in -"${SYSTEM}") - ppdreppath="${SYSTEMREP}" - ;; -"${ADMIN}") - ppdreppath="${ADMINREP}" - ;; -"${VENDOR}") - ppdreppath="${VENDORREP}" - ;; -"${USER}") - ppdreppath="${USERREP}" - ;; -"all") - if [[ "${action}" = "${ADD}" || \ - "${action}" = "${GENERATEENTRY}" ]] ; then - print -n "$myprog: " 1>&2 - gettext "reserved PPD repository name: " 1>&2 - gettext "${ppdrepname}\n" 1>&2 - ppdmgr_exit ${FAIL} - fi - ppdreppath="all" - ;; -"${UNSET}"|"") - ppdreppath="${UNSET}" - ;; - -*) - print -n "$myprog: " 1>&2 - gettext "invalid PPD repository name: ${ppdrepname}\n" 1>&2 - ppdmgr_exit ${FAIL} - ;; -esac - -# -# When a source PPD file's path is from a known repository, the -# destination repository and desination label are assumed to be the -# same as the source PPD file's unless a differing repository or label -# was specified. -# -if [[ "${action}" = "${ADD}" || "${action}" = "${GENERATEENTRY}" ]] ; then - - srcppdpath=$(ppd_pathname "${origsrcppdpath}") - ppd_pathname_rc=$? - if [[ ${ppd_pathname_rc} -ne 0 ]] ; then - print -n "$myprog: " 1>&2 - gettext "invalid PPD file: ${origsrcppdpath}\n" 1>&2 - ppdmgr_exit ${ppd_pathname_rc} - fi - - # Path cannot contain special characters - echo "${srcppdpath}" | /bin/egrep "${SPECIALCHARS}" >/dev/null - if [[ $? -eq 0 ]] ; then - print -n "$myprog: " 1>&2 - gettext "PPD path contains " 1>&2 - gettext "an invalid character: ${ppd_pathname}\n" 1>&2 - ppdmgr_exit ${FAIL} - fi - ppdfname=$(/bin/basename "${origsrcppdpath}") - - # - # Check to see if there's any work to be done. If the source file - # is already in the destination repository under the destination - # label, then there's nothing left to do. We exit rather than - # going on to do an update on the label in the repository as - # it could possible take a long time to update. If an add was - # requested, it could have come from an application, so we want - # to return quickly. - # - if label_path_match "${srcppdpath}" "${ppdreppath}" "${ppdlabel}" ; then - if [[ ${wflag} -eq 1 || \ - "${action}" = "${GENERATEENTRY}" ]] ; then - echo "${srcppdpath}" - fi - ppdmgr_exit ${SUCCESS} - fi -fi - -ppdlabel=$(valid_specified_label "${ppdlabel}") -if [[ $? -ne 0 ]] ; then - ppdmgr_exit ${FAIL} -fi - -if [[ "${ppdreppath}" = "${UNSET}" ]] ; then - ppdreppath="${USERREP}" -fi - -dstrepname=$(get_rep_name "${ppdreppath}") - -case "${action}" in -"${ADD}") - # - # Attempt to add the PPD file to the repository under the - # specified label. If any errors occur, final_dst_ppd_path - # will contain the error message rather than the path to the - # PPD file. - # - final_dst_ppd_path=$(add_ppd "${srcppdpath}" "${ppdfname}" \ - "${ppdreppath}" "${dstrepname}" "${ppdlabel}") - add_ppd_rc=$? - case ${add_ppd_rc} in - 0) # - # The PPD file was added. Update the specified - # cache associated with the label if the PPD file - # was added successfully and was not a duplicate. - # Ensure any changes are also reflected in the - # golden cache. - # - add_ppd_msg=$(update_label_cache "${ppdreppath}" \ - "${dstrepname}" "${ppdlabel}") - apm_rc=$? - - echo "${add_ppd_msg}" | /bin/grep "${final_dst_ppd_path}" - path_in_msg=$? - - # - # Only report cache update errors if the file that was - # added was one that was reported as not being added - # to the cache. This really should happen as the file - # was verified during the add. - # - if [[ ${apm_rc} -ne 0 && ${path_in_msg} -eq 0 ]] ; then - print -n "$myprog: " 1>&2 - gettext "printer information does not reflect " 1>&2 - gettext "the\nfollowing PPD file(s):\n" 1>&2 - print "${add_ppd_msg}" 1>&2 - status=${FAIL} - else - update_golden_cache - - # - # Display the full path to the added PPD file, - # if requested (-w). - # - if [[ ${wflag} -eq 1 ]] ; then - print "${final_dst_ppd_path}" - fi - fi - ;; - - 1) # Duplicate copy exists - if [[ ${wflag} -eq 1 ]] ; then - print "${final_dst_ppd_path}" - fi - ;; - - 2) # Varying copy exists - print -n "$myprog: " 1>&2 - gettext "differing variant of source PPD file " 1>&2 - gettext "already exists at\n" 1>&2 - gettext "${final_dst_ppd_path}\n" 1>&2 - status=${FAIL} - ;; - *) # The PPD file was not added as a problem occurred. - # Display the error message. - print -n "$myprog: " 1>&2 - print "${final_dst_ppd_path}" 1>&2 - status=${FAIL} - ;; - - esac - ;; - -"${GENERATEENTRY}") - # - # Create a cache file entry for the specified PPD file and - # display it on standard out. - # - verify_ppd_file "${srcppdpath}" - if [[ $? -eq 0 ]] ; then - dstdir="${ppdreppath}/${ppdlabel}/${modmanuf}" - final_dst_path="${dstdir}/$(/bin/basename ${srcppdpath})" - verify_ppd_location "${final_dst_path}" - if [[ $? -eq 0 ]] ; then - # Generate the cache file entry - print "$(generate_cache_file_entry "${modmanuf}" \ - "${model}" "${nickn}" "${devidmfg}" "${devidmdl}" \ - "${final_dst_path}")" - else - print -n "$myprog: " 1>&2 - gettext "PPD file not in valid location\n" 1>&2 - gettext \ - "(<repository>/<label>/<manufacturer>/<PPD file>):\n\t${1}\n" 1>&2 - status=${FAIL} - fi - - else - print -n "$myprog: " 1>&2 - gettext "invalid PPD file: ${1}\n" 1>&2 - status=${FAIL} - fi - ;; - -"${REBUILD}" | "${UPDATE}") - update_msg=$(update_cache "${ppdreppath}" "${ppdlabel}") - if [[ $? -ne 0 ]] ; then - print -n "$myprog: " 1>&2 - gettext "printer information does not reflect " 1>&2 - gettext "the\nfollowing PPD file(s):\n" 1>&2 - print "${update_msg}" 1>&2 - status=${WARN} - fi - ;; - -*) - usage - ;; -esac - -ppdmgr_exit ${status} |