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