8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / print / scripts / ppdmgr
blob335c01da7dbfb26270797311fd054a0cbc0bee07
1 #!/bin/ksh
3 # CDDL HEADER START
5 # The contents of this file are subject to the terms of the
6 # Common Development and Distribution License (the "License").
7 # You may not use this file except in compliance with the License.
9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 # or http://www.opensolaris.org/os/licensing.
11 # See the License for the specific language governing permissions
12 # and limitations under the License.
14 # When distributing Covered Code, include this CDDL HEADER in each
15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 # If applicable, add the following below this CDDL HEADER, with the
17 # fields enclosed by brackets "[]" replaced with your own identifying
18 # information: Portions Copyright [yyyy] [name of copyright owner]
20 # CDDL HEADER END
22 # Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 # Use is subject to license terms.
27 # Description: Script to generate the Solaris printmgr 'ppdcache' file from the
28 # ppd files installed in the given ppd database directory
30 # ppdmgr -a <ppd_filename_path> [ -L <label> ] [-w]
31 # ppdmgr -g <ppd_filename_path> [ -L <label> ] [ -R <ppd_repository> ]
32 # ppdmgr -r [ -L <label> ] [ -R <ppd_repository> ]
33 # ppdmgr -u [ -L <label> ] [ -R <ppd_repository> ]
35 # Options:
36 # -a <ppd_filename_path> - Add a new PPD file to the specified
37 # label in the "user" repository, and
38 # updates to the "user" repository
39 # in the ppdcache.
40 # -g <ppd_filename_path> - Generate a cache file entry
41 # for the specified PPD file
42 # on standard out.
43 # -L <label> - Label name. <label>
44 # can be any characters from the
45 # portable character set, however
46 # may not contain a semi-colon (':').
47 # The following are the defaults
48 # for <label> for each option:
49 # OPTION DEFAULT LABEL
50 # ------ -------------
51 # -a <label> from <ppd_filename_path>
52 # if <ppd_filename_path>
53 # is from a known repository,
54 # otherwise defaults to "user".
55 # -g <label> from <ppd_filename_path>
56 # if <ppd_filename_path>
57 # is from a known repository,
58 # otherwise defaults to "user".
59 # -r all
60 # -u all
61 # The following are reserved labels:
62 # caches - may never be specified
63 # ppdcache - may never be specified
64 # manufaliases - may never be specified
65 # all - applies specified
66 # action to all labels
67 # in a repository.
68 # Can only be specified
69 # with -r or -u.
70 # SUNW* - anything starting with
71 # SUNW is reserved for
72 # use by Sun, but not
73 # prohibited.
74 # -r - Rebuild the cache information for the
75 # specified label in the specified
76 # repository. Similar to -u, however,
77 # the cache file is removed to force an
78 # update to the ppdcache.
79 # -R <ppd_repository> - PPD repository name.
80 # Defaults to "user".
81 # The following are the possible
82 # values for <ppd_repository> and
83 # location in the system:
84 # REP LOCATION
85 # --- --------
86 # user /var/lp/ppd
87 # admin /usr/local/share/ppd
88 # vendor /opt/share/ppd
89 # system /usr/share/ppd
90 # all all repositories
92 # Note: When specified with the -a option
93 # only "user" and "admin" are valid.
94 # "vendor", "system", and "all" will be
95 # considered reserved.
96 # -u - Update the PPD cache information
97 # for the specified label in the specified
98 # repository if needed. If the cache
99 # update was required, then the updated
100 # cache information is reflected in
101 # the ppdcache.
102 # -w - Display full path of where the
103 # ppd file is located on the system.
104 # Only valid with -a, otherwise the
105 # option is ignored.
107 # If -a, -g, -r, or -u are specified on the command line, only the last action
108 # specified will be performed.
110 # Cache file entry format:
111 # <ModifiedManufacturerName>:<Model>:<NickName>:<1284DeviceIDManufacturer>:<1284DeviceIDModel>:<FullPPDFilePath>
112 # HP:HP DeskJet 450:Foomatic/hpijs (recommended):dj450:hp:/usr/share/ppd/HP/HP-DeskJet_450-hpijs.ppd.gz
115 PATH=/bin:/usr/bin:/usr/sbin export PATH
116 set -o noclobber
118 TEXTDOMAIN="SUNW_OST_OSCMD"
119 export TEXTDOMAIN
122 # Generates debug output for calling routine.
123 # If calling routine's name is passed in, then
124 # will also generate the name of the calling routine.
126 # $1 - Name of calling routine
127 debugger()
129 [[ ${debug} -eq 1 ]] || return 1
130 if [[ -n "${1}" ]] ; then
131 echo "In ${1}..." 1>&2
133 return 0
137 # Set the ownership and permissions on a file.
139 # $1 - Mode
140 # $2 - Owner:Group
141 # $3 - Full path to file
143 set_perms()
145 /bin/chmod -f ${1} "${3}" >/dev/null 2>&1
146 /bin/chown -f ${2} "${3}" >/dev/null 2>&1
150 # Create administrator repository directories, /usr/local/share/ppd,
151 # if needed. This is a special case a Solaris doesn't deliver
152 # /usr/local/share and it has different permissions than the
153 # user repository.
155 # $1 - destination repository name
157 create_adminrep_dirs()
159 if debugger "check_adminrep_dirs" ; then
160 set -x
163 # Only create administrator repository directories, if needed.
164 [[ "${1}" = "${ADMIN}" ]] || return 0
166 # Check /usr/local/share/ppd
167 [[ ! -d "${ADMINREP}" ]] || return 0
169 # Check /usr/local/share
170 admpar=$(/bin/dirname "${ADMINREP}")
171 if [[ ! -d "${admpar}" ]] ; then
173 # Check /usr/local
174 admppar=$(/bin/dirname "${admpar}")
175 if [[ ! -d "${admppar}" ]] ; then
176 make_dir ${DIRMODE} ${ADMINOWNER} "${admppar}" || \
177 return 1
179 make_dir ${DIRMODE} ${ADMINOWNER} "${admpar}" || return 1
181 make_dir ${DIRMODE} ${ADMINOWNER} ${ADMINREP} || return 1
182 return 0
186 # Returns full path to PPD file that was added to the system.
188 # $1 - Full path to source PPD file
189 # $2 - PPD file name
190 # $3 - Full path to repository
191 # $4 - Repository name
192 # $5 - Label name
194 # Return codes:
195 # 0 - File successfully added
196 # 1 - Error
197 # 2 - Duplicate file already exists
199 add_ppd()
201 if debugger ; then
202 set -x
205 verify_ppd_file "${1}"
206 if [[ $? -ne 0 ]] ; then
207 gettext "invalid PPD file: ${1}" 2>/dev/null
208 return 3
211 # The destination path can now be set
212 dstlabelpath="${3}/${5}"
213 dstmanufpath="${dstlabelpath}/${modmanuf}"
214 dstpath="${dstmanufpath}/${2}"
217 # If a version (either compressed or not compressed) of the PPD
218 # file exists in the destination in the label/repository,
219 # then just return as there no work to be done.
220 dst_copy_path=$(variant_copy "${1}" "${dstpath}" "${6}" "${ppdfname}")
221 ap_rc=$?
222 if [[ ${ap_rc} -ne 0 ]] ; then
223 echo "${dst_copy_path}"
224 return ${ap_rc}
228 # Can only add a PPD file to the "user" or "admin" repository.
229 # Note: this check is here instead of at the top of this
230 # function as we don't want to cause an error if a user
231 # specifies the same repository and label as a the specified
232 # ppd file and the repository of the specified ppd file
233 # exists in a known repository.
235 if [[ "${4}" != "${USER}" && "${4}" != "${ADMIN}" ]] ; then
236 gettext "invalid PPD file repository name: ${4}" 2>/dev/null
237 return 3
240 # Ensure destination directories exist
241 if ! create_adminrep_dirs ${4} ${DIRMODE} ${ADMINOWNER} || \
242 ! make_dir ${DIRMODE} ${DIROWNER} "${3}" || \
243 ! make_dir ${DIRMODE} ${DIROWNER} "${dstlabelpath}" || \
244 ! make_dir ${DIRMODE} ${DIROWNER} "${dstmanufpath}" ; then
245 gettext "unable to create destination directories" 2>/dev/null
246 return 3
249 # Copy source PPD file, and compress if needed, to destination
250 if [[ "${ppdfileext}" = "${PEXT}" ]] ; then
251 ${GZIP} "${1}" >"${dst_copy_path}" 2>/dev/null
252 if [[ $? -eq 1 ]] ; then
253 gettext "unable to copy PPD file " 2>/dev/null
254 gettext "to destination" 2>/dev/null
255 return 3
257 else
258 /bin/cp -f "${1}" "${dst_copy_path}" >/dev/null 2>&1
259 if [[ $? -ne 0 ]] ; then
260 gettext "unable to copy PPD file " 2>/dev/null
261 gettext "to destination" 2>/dev/null
262 return 3
265 set_perms ${FILEMODE} ${FILEOWNER} "${dst_copy_path}"
267 echo "${dst_copy_path}"
269 return 0
273 # Returns 0 if the cache needs to be modified, otherwise
274 # returns 1.
276 # $1 - Full path to cache
277 # $2 - Full path to cache replacement candidate
279 changes_in_cache()
281 if debugger "changes_in_cache" ; then
282 set -x
285 if [[ "${action}" = "${REBUILD}" ]] ; then
286 return 0
288 [[ "${2}" -nt "${1}" ]] || return 1
289 if $(${CMP} "${1}" "${2}" >/dev/null 2>&1) ; then
290 # No differences. Just update timestamp
291 /bin/touch -r "${2}" "${1}" >/dev/null 2>&1
292 return 1
293 else
294 return 0
299 # Generate a new golden cache file (/var/lp/ppd/ppdcache), by
300 # concatenating and sorting all existing cache files in /var/lp/ppd/caches.
302 # If there are difference between the newly generated golden cache file and
303 # the existing one (if it exists) then the newly generated one replaces the
304 # existing one at /var/lp/ppd/ppdcache.
306 update_golden_cache()
309 if debugger "update_golden_cache" ; then
310 set -x
314 # Remove any cache files that don't have an associated
315 # label.
317 for cname in $(/bin/ls ${VARCACHES} 2>/dev/null) ; do
318 repname="${cname%%:*}"
319 cfile="${cname#*:}"
320 checkdir="$(get_rep_path ${repname})/${cfile}"
321 remove_unassociated_cache "${checkdir}" "${cname}"
322 done
325 # Combine the contents of all cache files into a
326 # temporary golden cache file.
328 tmpgoldencache=$ppdmgrtmpdir/tmpgoldencache
330 /bin/sort "${VARCACHES}"/* >>"${tmpgoldencache}" 2>/dev/null
332 if [[ ! -s "${tmpgoldencache}" ]] ; then
333 # No cache files. Remove golden cache.
334 /bin/rm -f "${GOLDCACHE}" >/dev/null 2>&1
335 /bin/rm -f "${tmpgoldencache}" >/dev/null 2>&1
336 elif [[ -e "${GOLDCACHE}" ]] ; then
338 # Use the newly generated "temporary" golden cache file if there
339 # differences between the current and newly generated ppdcache
340 # or if a rebuild is being performed.
342 if [[ "${VARCACHES}" -nt "${GOLDCACHE}" ]] || \
343 changes_in_cache "${GOLDCACHE}" "${tmpgoldencache}" ; then
344 set_perms ${FILEMODE} ${FILEOWNER} "${tmpgoldencache}"
345 /bin/mv -f "${tmpgoldencache}" \
346 "${GOLDCACHE}" >/dev/null 2>&1
347 else
348 /bin/rm -f "${tmpgoldencache}" >/dev/null 2>&1
350 else
351 # There wasn't an existing ppdcache. Install the newly
352 # generated ppdcache file to the golden ppdcache.
353 set_perms ${FILEMODE} ${FILEOWNER} "${tmpgoldencache}"
354 /bin/mv -f "${tmpgoldencache}" "${GOLDCACHE}" >/dev/null 2>&1
359 # Returns a list of PPD files that exist.
361 # $1 - Full path to cache file
363 remove_invalid_cache_entries()
365 if debugger ; then
366 set -x
369 [[ -s "${1}" ]] || return
371 IFS="$NoSpaceTabIFS"
372 for centry in $(/bin/cat "${1}" 2>/dev/null) ; do
373 IFS="$SaveIFS"
375 # Keep the entry from the ppd cache if it still
376 # exists and there haven't been any modifications
377 # since the last update to the cache.
379 if [[ -n "${centry}" ]] ; then
380 ppdfile="${centry##*:}"
381 if [[ -n "${ppdfile}" && -e "${ppdfile}" &&
382 "${1}" -nt "${ppdfile}" ]] ; then
383 echo "${centry}"
386 IFS="$NoSpaceTabIFS"
387 done
388 IFS="$SaveIFS"
392 # Returns 0 if the path to the PPD is as follows:
393 # <PPD file repository>/<label>/<manufacturer>/<PPD file>
394 # otherwise, returns 1
396 # $1 Full path to PPD file
398 verify_ppd_location()
400 if debugger ; then
401 set -x
405 # Strip off what should be <label>/<manufacturer>/<PPD file>
406 # and verify the PPD file repository matches one of the
407 # known PPD file repositories.
409 ppd_file_repository=${1%/*/*/*}
410 found=1
411 for repository in ${REPOSITORIES} ; do
412 if [[ "${repository}" = "${ppd_file_repository}" ]] ; then
413 found=0
414 break
416 done
417 return ${found}
421 # Generate, and sort, cache entries for each PPD files in the specified
422 # list to the specified file.
424 # $1 - List of full paths to PPD files
425 # $2 - Full path to current cache file
426 # $3 - Full path to label
427 # $4 - Full path to new cache file to generate
429 # Return code:
430 # 0 success
431 # 1 unsuccessful
433 generate_label_cache_file()
435 if debugger ; then
436 set -x
440 # Generate a cache file containing cache entries for
441 # all files in the label.
443 ucfile=$ppdmgrtmpdir/unsortedcache
446 # Before processing new files, remove any cache entries
447 # which may be invalid.
449 valid_files=
450 if [[ -e "${2}" && "${action}" != "${REBUILD}" ]] ; then
451 valid_files=$(remove_invalid_cache_entries "${2}")
452 if [[ -n "${valid_files}" ]] ; then
453 echo "${valid_files}" >>${ucfile}
458 # If there are no valid PPD files in the current cache file,
459 # and there are no new PPD files to process, the only thing
460 # left to do is to remove the current cache file.
462 if [[ -z "${valid_files}" && -z "${1}" ]] ; then
463 /bin/rm -f "${2}" >/dev/null 2>&1
464 /bin/rm -f "${ucfile}" >/dev/null 2>&1
465 return 0
469 # For each of the label's PPD files, generate
470 # a cache file entry and add it to the cache file.
472 vpl_rc=0
473 vpf_rc=0
474 vpl_msg=
475 vpf_msg=
476 IFS="$NoSpaceTabIFS"
477 for fname in ${1} ; do
478 IFS="$SaveIFS"
479 if [[ -n "${fname}" ]] ; then
480 verify_ppd_location "${fname}"
481 vpl_rc=$?
482 if [[ ${vpl_rc} -ne 0 ]] ; then
483 vpl_msg="${vpl_msg}\t${fname}\n"
486 verify_ppd_file "${fname}"
487 vpf_rc=$?
488 if [[ ${vpf_rc} -ne 0 ]] ; then
489 vpf_msg="${vpf_msg}\t${fname}\n"
492 if [[ ${vpl_rc} -eq 0 && ${vpf_rc} -eq 0 ]] ; then
493 echo "$(generate_cache_file_entry \
494 "${modmanuf}" "${model}" "${nickn}" \
495 "${devidmfg}" "${devidmdl}" "${fname}")"
498 IFS="$NoSpaceTabIFS"
499 done >>"${ucfile}"
500 IFS="$SaveIFS"
501 /bin/sort -u "${ucfile}" >>"${4}" 2>/dev/null
502 /bin/rm -f "${ucfile}" >/dev/null 2>&1
504 [[ -n "${vpl_msg}" || -n "${vpf_msg}" ]] || return 0
505 if [[ -n ${vpl_msg} ]] ; then
506 gettext " PPD file(s) not in valid location\n" 2>/dev/null
507 gettext \
508 " (<repository>/<label>/<manufacturer>/<PPD file>):\n" 2>/dev/null
509 echo "${vpl_msg}"
511 if [[ -n ${vpf_msg} ]] ; then
512 gettext " invalid PPD file(s):\n" 2>/dev/null
513 echo "${vpf_msg}"
515 return 1
519 # Update current cache file with candidate cache file if there are
520 # differences.
522 # $1 - Current cache file
523 # $2 - Candidate cache file to update
524 # $3 - Repository name
526 update_current_cache_file()
528 if debugger "update_current_cache_file" ; then
529 set -x
532 if [[ ! -s "${2}" ]] ; then
534 # Candidate cache has zero size (label
535 # directory with no PPD files under it).
536 # Delete the empty candidate cache
537 # file and delete the current cache
538 # file.
540 /bin/rm -f "${1}" >/dev/null 2>&1
541 /bin/rm -f "${2}" >/dev/null 2>&1
542 elif [[ -e "${1}" ]] ; then
544 # If there are differences between the current
545 # cache file and the newly generated one, then
546 # replace the current one with the new one, and
547 # set the flag to update the golden ppdcache
548 # file.
550 if changes_in_cache "${1}" "${2}" ; then
551 set_perms ${FILEMODE} ${FILEOWNER} "${2}"
552 /bin/mv -f "${2}" "${1}" >/dev/null 2>&1
553 else
554 /bin/rm -f "${2}" >/dev/null 2>&1
556 else
559 # There is no current cache file. Move the candidate
560 # to the caches directory.
562 set_perms ${FILEMODE} ${FILEOWNER} "${2}"
563 /bin/mv -f "${2}" "${1}" >/dev/null 2>&1
568 # Returns 0 if there are files in $1 with newer timestamp
569 # than $2 or if deletions have occurred under $1,
570 # otherwise returns 1.
572 # $1 - Full path to the destination label
573 # $2 - Full path to label cache file
575 changes_under_label()
577 if debugger ; then
578 set -x
581 # First check for newer files in the directory
582 if [[ -e "${2}" && "${action}" != "${REBUILD}" ]] ; then
583 newfiles=$(/bin/find "${1}" -type f -newer "${2}")
584 else
585 newfiles=$(/bin/find "${1}" -type f)
587 echo "${newfiles}"
588 [[ -z "${newfiles}" ]] || return 0
591 # Need to detect if PPD files have been deleted by checking
592 # timestamps on label and manufacturer directories.
594 [[ ! "${1}" -nt "${2}" ]] || return 0
595 /bin/find "${1}" -type d -newer "${2}" >/dev/null 2>&1 || return 1
596 return 0
600 # If -R was specified, or the timestamp on the specified label's
601 # directory or any of the PPD files under the specified label in
602 # the specified PPD file respository is newer than the cache file
603 # associated with the label, then generate a new sorted cache file.
605 # The new cache will replace the existing one (if any) only if there
606 # are differences. Note: if -r was specified, then a new cache file
607 # file will always be installed at
608 # /var/lp/ppd/caches/<PPD file repository name>-<label name>
610 # $1 - Full path of the destination PPD file repository
611 # $2 - Destination PPD file repository name
612 # $3 - Destination label name
614 update_label_cache()
616 if debugger ; then
617 set -x
620 dstlabelpath="${1}/${3}"
621 replabelcachepath="${1}/${CACHES}/${3}"
622 varlabelcachepath="${VARCACHES}/${2}${SEP}${3}"
624 ulc_rc=0
625 if [[ -d "${dstlabelpath}" ]] ; then
628 # If the cache doesn't exist for a label,
629 # or if there were any changes under a label
630 # (i.e., the timestamp on the label directory or any
631 # of the PPD files under it is newer than the
632 # existing cache file), then generate a new cache file.
634 tmpcachepath=$ppdmgrtmpdir/tmpcachepath
636 # if this is a system repository, check for a prepopulated cache
637 if [[ "${2}" = "${SYSTEM}" && -e ${FOOCACHEDIR}/${3}.cache ]] ; then
638 # copy prepopulated cache
639 /bin/cp -f ${FOOCACHEDIR}/${3}.cache ${tmpcachepath}
641 else
642 newfileslist=$(changes_under_label "${dstlabelpath}" \
643 "${varlabelcachepath}")
644 if [[ $? -eq 0 ]] ; then
645 err_files=$(generate_label_cache_file \
646 "${newfileslist}" "${varlabelcachepath}" \
647 "${dstlabelpath}" "${tmpcachepath}")
648 if [[ $? -ne 0 ]] ; then
650 # At least one PPD file was invalid.
651 # Don't return yet, as the cache info
652 # for the valid PPD files can still be
653 # used to generate a cache file.
655 echo "${err_files}"
656 ulc_rc=1
661 if [[ -e "${tmpcachepath}" ]] ; then
662 update_current_cache_file \
663 "${varlabelcachepath}" "${tmpcachepath}" "${2}"
664 /bin/rm -f "${tmpcachepath}" >/dev/null 2>&1
666 else
668 # If there is a cache file in /var/lp/ppd/caches associated
669 # with the label which no longer exists, remove it.
671 /bin/rm -f "${varlabelcachepath}" >/dev/null 2>&1
673 return ${ulc_rc}
677 # Returns the alias for the specified real manufacturer's name.
679 # $1 - Real manufacturer's name
680 # $2 - File containing list of files that have manufacturers aliases
682 manuf_name_alias()
684 if debugger ; then
685 set -x
689 # Found a couple of PPD files which had special characters
690 # in the Manufacturer name (i.e, the following is the Manufacturer
691 # entry:
692 # *Manufacturer: "Canon Inc. (Kosugi Offic"
693 # We'll only search the alias file for "Canon Inc."
695 tmpmanuf="${1% *\(*}"
697 # Search alias files for a match on the real manufacturer name
698 if [[ -s "${2}" ]] ; then
700 # Check the manufacturer aliases file for case
701 # insensitive match of the Manufacturer entry
702 # from the PPD file. If a match is found,
703 # then modify the manufacturer entry to
704 # be that of the specified alias.
706 manufaliases=$(/bin/egrep -i \
707 "^${tmpmanuf}:|:${tmpmanuf}:|:${tmpmanuf}$" "${2}")
708 if [[ -n "${manufaliases}" ]] ; then
709 echo "${manufaliases%%:*}"
710 break
711 else
712 echo "${tmpmanuf}"
714 else
715 echo "${tmpmanuf}"
720 # Returns 0 if the extension to the specified PPD file is a known
721 # extension, otherwise returns 1.
723 # $1 - Full path to PPD file
725 # Set upon return:
726 # ppdfileext - PPD file ext (.ppd or .ppd.gz)
728 verify_file_ext()
730 if debugger ; then
731 set -x
734 if [[ "${1%.gz}".gz = "${1}" ]] ; then
735 ppdfileext=${GEXT}
736 elif [[ "${1%.ppd}".ppd = "${1}" ]] ; then
737 ppdfileext=${PEXT}
738 else
739 # invalid PPD file name extension
740 return 1
743 return 0
747 # Return the lines from the specified PPD file matching the specified
748 # spec items.
750 # $1 - spec entries from PPD file
751 # $2 - spec item
753 # $1 example - 1 string with substrings separated by newline:
754 # *PPD-Adobe: "4.3"
755 # *Manufacturer: "HP"
756 # *Product: "(officejet 4200 series)"
757 # *ModelName: "HP OfficeJet 4200"
758 # *NickName: "HP OfficeJet 4200 Foomatic/hpijs (recommended)"
759 # $2 example:
760 # ^\*Manufacturer
762 spec_entry()
764 if debugger ; then
765 set -x
768 item=$(echo "${1}" | /bin/grep ${2})
769 # Remove everything up to and including the first quote
770 item=${item#*\"}
771 # Remove the end quote
772 echo "${item%\"}"
776 # Return the lines from the specified PPD file matching the specified
777 # spec items.
779 # Note: this is similar to spec_entry() except the tokens in the
780 # spec entry are different.
782 # $1 - spec entries from PPD file
783 # $2 - spec item
785 devid_spec_entry()
787 if debugger ; then
788 set -x
791 item=$(echo "${1}" | /bin/grep ${2})
792 # Remove everything up to and including the first semi-colon
793 item=${item#*\:}
794 # Remove the end quote
795 echo ${item%\;}
800 # Verifies that the specified PPD file
801 # - has a valid extension
802 # - has the following required spec file entries:
803 # *PPD-Adobe: "4.3"
804 # Manufacturer
805 # Product
806 # ModelName
807 # NickName
809 # In addition, the manufacture and model from the IEEE1284 device id
810 # information will be gathered here, although it's not an error that
811 # it isn't in the PPD file as many don't contain the IEEE1284 info.
813 # $1 - Full path to PPD file
815 # Return codes:
816 # 0 success
817 # 1 invalid PPD file
819 verify_ppd_file()
821 if debugger ; then
822 set -x
825 ADOBESPEC="PPD-Adobe"
826 MANUF="Manufacturer"
827 PRODUCT="Product"
828 MODEL="ModelName"
829 NICKNAME="NickName"
830 DEVID="1284DeviceID"
832 # Verify the PPD file extension
833 verify_file_ext "${1}" || return 1
835 # Query for the required spec items
836 searchentries="^\*${ADOBESPEC}:|^\*${MANUF}:|^\*${PRODUCT}:"
837 searchentries="${searchentries}|^\*${MODEL}:|^\*${NICKNAME}:"
838 searchentries="${searchentries}|^\*${DEVID}:"
839 ppd_info="$(/bin/gzgrep -e "${searchentries}" "${1}")"
842 # Process the query results to verify each of the required spec
843 # file items appears in the PPD file.
845 for spec_item in ${ADOBESPEC} ${MANUF} ${PRODUCT} ${MODEL} \
846 ${NICKNAME} ; do
847 entry=$(spec_entry "${ppd_info}" "^\*${spec_item}:")
848 [[ ! -z "${entry}" ]] || return 1
849 case ${spec_item} in
850 ${MANUF})
851 realmanuf="${entry}"
853 ${PRODUCT})
854 product="${entry}"
856 ${MODEL})
857 model="${entry}"
859 ${NICKNAME})
861 # Remove the model and any commas and spaces
862 # which appear before the driver
864 nickn="${entry#$model[, ]*}"
866 esac
868 done
870 # Save IEEE1284 device id information
871 if $(echo "${ppd_info}" | grep "${DEVID}" >/dev/null 2>&1) ; then
872 DMDL="MDL"
873 DMFG="MFG"
874 devid="$(/bin/gzgrep -e "^[ ]*${DMDL}:|^[ ]*${DMFG}:" "${1}")"
875 devidmdl="$(devid_spec_entry "${devid}" "${DMDL}")"
876 devidmfg="$(devid_spec_entry "${devid}" "${DMFG}")"
877 else
878 devidmdl=
879 devidmfg=
881 modmanuf=$(manuf_name_alias "${realmanuf}" ${aliasfile})
883 return 0
887 # generate_cache_file_entry()
889 # Returns a cache file entry for the specified PPD file.
891 # $1 - modmanuf
892 # $2 - model
893 # $3 - nickn
894 # $4 - devidmfg
895 # $5 - devidmdl
896 # $6 - Full path to the specified PPD file
898 generate_cache_file_entry()
900 if debugger "generate_cache_file_entry" ; then
901 set -x
904 echo "${1}":"${2}":"${3}":"${4}":"${5}":"${6}"
908 # Expand specified file to the full path.
910 # $1 - File path to expand
912 # Return code set to 0 if expanded successfully, otherwise set to 1.
914 ppd_pathname()
916 if debugger ; then
917 set -x
920 if [[ -f "${1}" && -s "${1}" ]] ; then
921 (cd "$(/bin/dirname "${1}")" ; \
922 echo "$(/bin/pwd)/$(/bin/basename "${1}")") || return 1
923 return 0
924 else
925 return 1
930 # Returns the PPD repsitory path associated with the specified
931 # PPD repository name.
933 # $1 - Repository name
935 get_rep_path()
937 if debugger ; then
938 set -x
941 case ${1} in
942 ${SYSTEM})
943 echo "${SYSTEMREP}"
945 ${VENDOR})
946 echo "${VENDORREP}"
948 ${ADMIN})
949 echo "${ADMINREP}"
951 ${USER})
952 echo "${USERREP}"
955 echo "${UNSET}"
957 esac
961 # Returns the PPD respository name from the repository path
963 # $1 - PPD repository path
965 get_rep_name()
967 if debugger ; then
968 set -x
971 case ${1} in
972 ${SYSTEMREP})
973 echo "${SYSTEM}"
975 ${VENDORREP})
976 echo "${VENDOR}"
978 ${ADMINREP})
979 echo "${ADMIN}"
981 ${USERREP})
982 echo "${USER}"
984 "all")
985 echo "all"
988 echo "${UNSET}"
990 esac
994 # Returns 0 if a matching label name is found in the specified repository,
995 # otherwise returns 1.
997 # $1 - repository path
998 # $2 - label name
1000 label_path_in_repository()
1002 if debugger "label_path_in_repository" ; then
1003 set -x
1006 [[ "${1}" != "" && "${2}" != "" ]] || return 1
1007 lpir_rc=1
1008 for repository in ${REPOSITORIES} ; do
1009 if [[ "${repository}" = "${1}" && -d "${1}/${2}" ]] ; then
1010 lpir_rc=0
1011 break
1013 done
1014 return ${lpir_rc}
1018 # Returns 0 if the source label path is the same
1019 # as the destination label path, otherwise returns 1.
1021 # $1 - full path to source PPD file (source label path)
1022 # $2 - destination repository path
1023 # $3 - destination label name
1025 label_path_match()
1027 if debugger "label_path_match" ; then
1028 set -x
1031 # dest repository not specified
1032 if [[ "${2}" = "${UNSET}" ]] ; then
1033 # dest label not specified
1034 if [[ "${3}" = "${UNSET}" ]] ; then
1036 # We've found a match if the label path is in a known
1037 # repository.
1039 lpath="${1%/*/*}"
1040 label_path_in_repository \
1041 "${1%/*/*/*}" "${lpath##*/}" || return 1
1042 else
1044 # If the source label path exists in the
1045 # in a known repository, and the destination
1046 # label is the same as the source label,
1047 # then we'll assume the default destination
1048 # repository is the same as the source
1049 # destination repository.
1051 [[ "${1%/*/*}" = "${1%/*/*/*}/${3}" ]] || return 1
1052 label_path_in_repository "${1%/*/*/*}" "${3}" || \
1053 return 1
1056 # dest repository specified, dest label not specified
1057 elif [[ "${3}" = "${UNSET}" ]] ; then
1059 # If the destination repository path is the same as the
1060 # source repository, and if the source label exists in the
1061 # destination repository path, then we'll assume the default
1062 # destination label is the same as the source label.
1064 [[ "${2}" = "${1%/*/*/*}" ]] || return 1
1065 lpath="${1%/*/*}"
1066 label_path_in_repository "${2}" "${lpath##*/}" || return 1
1068 # dest repository and dest label specified.
1069 else
1071 # We've found a match if the destination and label
1072 # match those of the source label path, and the source
1073 # label path is in a known repository.
1075 [[ "${1%/*/*}" = "${2}/${3}" ]] || return 1
1076 label_path_in_repository "${2}" "${3}" || return 1
1078 return 0
1082 # Returns 0 if specified label name is a reserved label, otherwise
1083 # returns 1.
1085 # $1 - label name
1087 reserved_label()
1089 if debugger ; then
1090 set -x
1093 rl_rc=1
1094 for labelname in ${RESERVEDLABELS} ; do
1095 if [[ "${1}" = "${labelname}" ]] ; then
1096 rl_rc=0
1097 break
1099 done
1100 return ${rl_rc}
1104 # Returns a list of all labels that exist in a repository that are
1105 # not reserved labels.
1107 # $1 - Full path of repository
1108 # $2 - Repository name
1110 get_rep_label_list()
1112 if debugger ; then
1113 set -x
1117 # Get a list of all labels that exist in all of the
1118 # PPD file repository.
1120 for lname in $(/bin/ls "${1}" 2>/dev/null) ; do
1121 if [[ -d "${1}/${lname}" ]] ; then
1122 if ! reserved_label "${lname}" ; then
1123 echo "${lname} "
1126 done
1130 # Returns a valid PPD label.
1132 # Verifies the specified PPD label is a valid label. If the
1133 # label is not set, then it is set to a default value.
1135 # Return code set to 0 if the specified PPD label is valid, otherwise 1.
1137 # $1 - PPD label
1139 valid_specified_label()
1141 if debugger ; then
1142 set -x
1145 # Verify the specified label
1146 vsl_rc=0
1147 case "${1}" in
1148 "all")
1149 # Reserved label name with -a or -g options
1150 if [[ "${action}" = "${ADD}" || \
1151 "${action}" = "${GENERATEENTRY}" ]] ; then
1152 print -n "$myprog: " 1>&2
1153 gettext "reserved PPD label name: ${1}\n" 1>&2
1154 vsl_rc=1
1155 else
1156 echo "${1}"
1160 "ppdcache" | "caches" | "manufaliases")
1161 # Reserved label names with any option
1162 print -n "$myprog: " 1>&2
1163 gettext "reserved PPD label name: ${1}\n" 1>&2
1164 vsl_rc=1
1167 "" | "${UNSET}")
1168 # Label name not specified. Set the default label name.
1169 # For -g and -a, default is "user", otherwise, default
1170 # is "all".
1171 if [[ "${action}" = "${ADD}" || \
1172 "${action}" = "${GENERATEENTRY}" ]] ; then
1173 echo "${USER}"
1174 else
1175 echo "all"
1180 # label cannot be "." or ".."
1181 if [[ "${1}" = "." || "${1}" = ".." ]] ; then
1182 print -n "$myprog: " 1>&2
1183 gettext "PPD label name cannot be " 1>&2
1184 gettext "\".\" or \"..\"\n" 1>&2
1185 vsl_rc=1
1188 # Label name cannot contain special characters
1189 echo "${1}" | /bin/egrep "${SPECIALCHARS}" >/dev/null
1190 if [[ $? -eq 0 ]] ; then
1191 print -n "$myprog: " 1>&2
1192 gettext "PPD label name contains " 1>&2
1193 gettext "an invalid character: ${1}\n" 1>&2
1194 vsl_rc=1
1195 else
1196 echo "${1}"
1199 esac
1200 return ${vsl_rc}
1204 # Returns the full path of any variant copy of the source file in
1205 # the destination label/repository.
1207 # $1 - Full path to source PPD file
1208 # $2 - Full path to destination PPD file
1210 # Return code set to
1211 # 0 - Copy doesn't exist
1212 # 1 - Duplicate copy exists
1213 # 2 - Variant copy exists
1215 variant_copy()
1217 if debugger ; then
1218 set -x
1222 # First make sure there is not a .ppd and a .ppd.gz version
1223 # of the destination file; users should know not to do this.
1225 if [[ -e "${2%.gz}" && -e "${2%.gz}.gz" ]] ; then
1226 /bin/rm -f "${2%.gz}" >/dev/null 2>&1
1229 # Use gzcmp to compare PPD files as it can deal with
1230 # gzipped or regular files.
1231 if $(${GZCMP} "${1}" "${2}"* >/dev/null 2>&1) ; then
1232 echo "${2}"*
1233 return 1
1234 elif [[ -e "${2%.gz}" ]] ; then
1235 echo "${2%.gz}"
1236 return 2
1237 elif [[ -e "${2%.gz}.gz" ]] ; then
1238 echo "${2%.gz}.gz"
1239 return 2
1240 else
1242 # A PPD file doesn't exist in the destination
1243 # repository under the destination label.
1244 # Just display the source PPD file, ensuring
1245 # it has a gzip extension as we will always
1246 # try to gzip the copy in the destination.
1248 if [[ "${1#*.ppd}" = ".gz" ]] ; then
1249 echo "${2}"
1250 else
1251 echo "${2}.gz"
1253 return 0
1258 # $1 - Directory mode
1259 # $2 - Directory owner (i.e., root:lp)
1260 # $3 - Directory to create
1262 make_dir()
1264 if debugger "make_dir" ; then
1265 set -x
1268 [[ ! -d "${3}" ]] || return 0
1269 /bin/mkdir "${3}" >/dev/null 2>&1 || return 1
1270 set_perms ${1} ${2} "${3}"
1271 return 0
1275 # Remove a ppdmgr generated cache (in /var/lp/ppd/cache)
1276 # if it doesn't have an associated label in the repository.
1278 # $1 - Full path to label
1279 # $2 - Cache name
1281 remove_unassociated_cache()
1283 if debugger "remove_unassociated_cache" ; then
1284 set -x
1287 if [[ "${1}" != "${UNSET}" ]] ; then
1288 if [[ -n "${1}" && ! -d "${1}" ]] ; then
1290 # The label doesn't exist, so delete
1291 # the associated cache file.
1293 /bin/rm -f "${VARCACHES}/${2}" >/dev/null 2>&1
1299 # Sorted copies of cache files for each label in each PPD repository
1300 # are maintained in /var/lp/ppd/caches/<PPD respository>-<label>.
1301 # This is done so that changes in delivered cache files can be
1302 # detected. If a difference in cache files is detected, or a
1303 # cache file is either added or removed, then we know that
1304 # the ppdcache file needs to be updated.
1306 # Get a list of all cache files and compare against the list
1307 # of labels in all of the PPD file repositories. They should
1308 # be the same. If there is a label in one of the PPD file
1309 # repositories that doesn't have an associated cache file, then
1310 # we don't worry about it now, as that will be resolved when
1311 # we update the cache for that label. However, if there is
1312 # a cache file associated with a label that no longer exists, then
1313 # remove the cache file.
1315 # $1 - Full path to repository (or "all")
1316 # $2 - Label name
1318 update_cache()
1320 if debugger ; then
1321 set -x
1325 # Determine which labels in which PPD repository the
1326 # cache file will be updated for.
1328 if [[ "${1}" = "all" ]] ; then
1329 rname="${REPOSITORIES}"
1330 else
1331 rname="${1}"
1334 uc_rc=0
1335 for dstreppath in ${rname} ; do
1336 labellist=
1337 if [[ "${2}" = "all" ]] ; then
1338 dstrepname=$(get_rep_name "${dstreppath}")
1339 labellist=$(get_rep_label_list "${dstreppath}" \
1340 "${dstrepname}")
1341 else
1343 # Ensure the label exists in the PPD file repository.
1344 if [[ -d "${dstreppath}/${2}" ]] ; then
1345 labellist="${2}"
1350 # Update the cache for each label in the PPD repository
1352 for dstlabel in ${labellist} ; do
1353 ulc_msg=$(update_label_cache "${dstreppath}" \
1354 "${dstrepname}" "${dstlabel}")
1355 if [[ $? -ne 0 ]] ; then
1356 echo "${ulc_msg}"
1357 uc_rc=1
1359 done
1360 done
1362 # Update the golden cache file.
1363 update_golden_cache
1364 return ${uc_rc}
1367 # $1 - exit status
1368 ppdmgr_exit()
1370 if debugger "ppdmgr_exit" ; then
1371 set -x
1374 /bin/rm -rf "${ppdmgrtmpdir}" >/dev/null 2>&1
1375 exit ${1}
1379 usage()
1381 gettext "usage:\n" 1>&2
1382 print -n "\t$myprog: " 1>&2
1383 gettext "-a <ppd_filename_path> [ -L <label> ]\n" 1>&2
1384 gettext "\t\t[ -R <ppd_repository> ] [-w]\n" 1>&2
1385 print -n "\t$myprog: " 1>&2
1386 gettext "-r [ -L <label> ] [ -R <ppd_repository> ]\n" 1>&2
1387 print -n "\t$myprog: " 1>&2
1388 gettext "-u [ -L <label> ] [ -R <ppd_repository> ]\n" 1>&2
1390 ppdmgr_exit ${FAIL}
1393 ##########################################################################
1394 # main
1395 ##########################################################################
1397 myprog=$(/bin/basename $0)
1399 SaveIFS="$IFS"
1400 NoSpaceTabIFS='
1403 # Updatable PPD repository
1404 VARDIR=/var/lp/ppd
1406 # Delivered PPD respository
1407 SYSTEMREP=/usr/share/ppd
1408 ADMINREP=/usr/local/share/ppd
1409 VENDORREP=/opt/share/ppd
1410 USERREP=${VARDIR}
1412 RESERVEDREPS="${SYSTEMREP} ${ADMINREP} ${VENDORREP}"
1413 REPOSITORIES="${USERREP} ${RESERVEDREPS}"
1414 RESERVEDLABELS="all caches ppdcache manufaliases"
1416 # Directory where system:SUNWfoomatic is delivered
1417 FOOCACHEDIR=/usr/lib/lp/caches
1419 # Deliveries
1420 SYSTEM=system
1421 VENDOR=vendor
1422 ADMIN=admin
1423 USER=user
1425 # Sytem PPD cache name used by printmgr
1426 GOLDCACHE=${USERREP}/ppdcache
1428 # Delivered caches directory
1429 CACHES=caches
1430 MANUFALIASES=manufaliases
1432 # Updated caches directory
1433 VARCACHES=${VARDIR}/${CACHES}
1435 # valid PPD file name extensions
1436 PEXT=ppd
1437 GEXT=gz
1438 FILEEXTS=".${PEXT} .${PEXT}.${GEXT}"
1440 # Default modes and owners
1441 DIRMODE=755
1442 DIROWNER=root:lp
1443 ADMINOWNER=root:root
1444 FILEMODE=444
1445 FILEOWNER=root:lp
1447 # ppdmgr actions
1448 ADD=add
1449 GENERATEENTRY=generateentry
1450 UPDATE=update
1451 REBUILD=rebuild
1453 SUCCESS=0
1454 FAIL=1
1455 WARN=2
1457 MAXLABELNAME=256
1458 GZIP="/bin/gzip -c"
1459 GZCMP="/bin/gzcmp -s"
1460 CMP="/bin/cmp -s"
1461 SPECIALCHARS=":"
1462 SEP=":"
1464 debug=0
1465 wflag=0
1466 status=${SUCCESS}
1468 UNSET="\f"
1469 ppdlabel=${UNSET}
1470 ppdrepname=${UNSET}
1471 ppdreppath=${UNSET}
1472 modmanuf=
1473 model=
1474 nickn=
1475 devidmdl=
1476 devidmfg=
1478 ppdmgrtmpdir=$(/usr/bin/mktemp -t -d ppdmgr.XXXXXX)
1479 if [ -z "$ppdmgrtmpdir" ] ; then
1480 print -n "$myprog: " 1>&2
1481 gettext "Fatal error: could not create temporary directory\n" 1>&2
1482 exit 1
1485 aliasfile=${USERREP}/manufaliases
1486 tmpfilepath=
1489 OPTS=a:g:L:rR:uwZ
1490 while getopts "$OPTS" arg ; do
1491 case ${arg} in
1492 a) # add PPD file
1493 action=${ADD}
1494 origsrcppdpath=${OPTARG}
1497 g) # create cache entry
1498 action=${GENERATEENTRY}
1499 origsrcppdpath=${OPTARG}
1502 L) # PPD label name
1503 ppdlabel=${OPTARG}
1506 r) # rebuild cache
1507 action=${REBUILD}
1510 R) # PPD file repository to use
1511 ppdrepname=${OPTARG}
1514 u) # update cache
1515 action=${UPDATE}
1518 w) # display PPD file path
1519 wflag=1
1522 Z) # debug
1523 debug=1
1527 usage
1529 esac
1530 done
1532 if debugger "Main" ; then
1533 set -x
1536 if [[ $# -lt 1 || -z "${action}" ]] ; then
1537 usage
1540 # ignore wflag unless specified with -a
1541 if [[ ${wflag} -eq 1 && "${action}" != ${ADD} ]] ; then
1542 wflag=0
1546 # Ensure the destination PPD repository directory is set
1547 # to match the specified repository. If the
1548 # destination PPD file repository was specified, then
1549 # it must be one of the following:
1550 # "user"
1551 # "admin"
1552 # "vendor"
1553 # "system"
1554 # "all"
1556 case "${ppdrepname}" in
1557 "${SYSTEM}")
1558 ppdreppath="${SYSTEMREP}"
1560 "${ADMIN}")
1561 ppdreppath="${ADMINREP}"
1563 "${VENDOR}")
1564 ppdreppath="${VENDORREP}"
1566 "${USER}")
1567 ppdreppath="${USERREP}"
1569 "all")
1570 if [[ "${action}" = "${ADD}" || \
1571 "${action}" = "${GENERATEENTRY}" ]] ; then
1572 print -n "$myprog: " 1>&2
1573 gettext "reserved PPD repository name: " 1>&2
1574 gettext "${ppdrepname}\n" 1>&2
1575 ppdmgr_exit ${FAIL}
1577 ppdreppath="all"
1579 "${UNSET}"|"")
1580 ppdreppath="${UNSET}"
1584 print -n "$myprog: " 1>&2
1585 gettext "invalid PPD repository name: ${ppdrepname}\n" 1>&2
1586 ppdmgr_exit ${FAIL}
1588 esac
1591 # When a source PPD file's path is from a known repository, the
1592 # destination repository and desination label are assumed to be the
1593 # same as the source PPD file's unless a differing repository or label
1594 # was specified.
1596 if [[ "${action}" = "${ADD}" || "${action}" = "${GENERATEENTRY}" ]] ; then
1598 srcppdpath=$(ppd_pathname "${origsrcppdpath}")
1599 ppd_pathname_rc=$?
1600 if [[ ${ppd_pathname_rc} -ne 0 ]] ; then
1601 print -n "$myprog: " 1>&2
1602 gettext "invalid PPD file: ${origsrcppdpath}\n" 1>&2
1603 ppdmgr_exit ${ppd_pathname_rc}
1606 # Path cannot contain special characters
1607 echo "${srcppdpath}" | /bin/egrep "${SPECIALCHARS}" >/dev/null
1608 if [[ $? -eq 0 ]] ; then
1609 print -n "$myprog: " 1>&2
1610 gettext "PPD path contains " 1>&2
1611 gettext "an invalid character: ${ppd_pathname}\n" 1>&2
1612 ppdmgr_exit ${FAIL}
1614 ppdfname=$(/bin/basename "${origsrcppdpath}")
1617 # Check to see if there's any work to be done. If the source file
1618 # is already in the destination repository under the destination
1619 # label, then there's nothing left to do. We exit rather than
1620 # going on to do an update on the label in the repository as
1621 # it could possible take a long time to update. If an add was
1622 # requested, it could have come from an application, so we want
1623 # to return quickly.
1625 if label_path_match "${srcppdpath}" "${ppdreppath}" "${ppdlabel}" ; then
1626 if [[ ${wflag} -eq 1 || \
1627 "${action}" = "${GENERATEENTRY}" ]] ; then
1628 echo "${srcppdpath}"
1630 ppdmgr_exit ${SUCCESS}
1634 ppdlabel=$(valid_specified_label "${ppdlabel}")
1635 if [[ $? -ne 0 ]] ; then
1636 ppdmgr_exit ${FAIL}
1639 if [[ "${ppdreppath}" = "${UNSET}" ]] ; then
1640 ppdreppath="${USERREP}"
1643 dstrepname=$(get_rep_name "${ppdreppath}")
1645 case "${action}" in
1646 "${ADD}")
1648 # Attempt to add the PPD file to the repository under the
1649 # specified label. If any errors occur, final_dst_ppd_path
1650 # will contain the error message rather than the path to the
1651 # PPD file.
1653 final_dst_ppd_path=$(add_ppd "${srcppdpath}" "${ppdfname}" \
1654 "${ppdreppath}" "${dstrepname}" "${ppdlabel}")
1655 add_ppd_rc=$?
1656 case ${add_ppd_rc} in
1657 0) #
1658 # The PPD file was added. Update the specified
1659 # cache associated with the label if the PPD file
1660 # was added successfully and was not a duplicate.
1661 # Ensure any changes are also reflected in the
1662 # golden cache.
1664 add_ppd_msg=$(update_label_cache "${ppdreppath}" \
1665 "${dstrepname}" "${ppdlabel}")
1666 apm_rc=$?
1668 echo "${add_ppd_msg}" | /bin/grep "${final_dst_ppd_path}"
1669 path_in_msg=$?
1672 # Only report cache update errors if the file that was
1673 # added was one that was reported as not being added
1674 # to the cache. This really should happen as the file
1675 # was verified during the add.
1677 if [[ ${apm_rc} -ne 0 && ${path_in_msg} -eq 0 ]] ; then
1678 print -n "$myprog: " 1>&2
1679 gettext "printer information does not reflect " 1>&2
1680 gettext "the\nfollowing PPD file(s):\n" 1>&2
1681 print "${add_ppd_msg}" 1>&2
1682 status=${FAIL}
1683 else
1684 update_golden_cache
1687 # Display the full path to the added PPD file,
1688 # if requested (-w).
1690 if [[ ${wflag} -eq 1 ]] ; then
1691 print "${final_dst_ppd_path}"
1696 1) # Duplicate copy exists
1697 if [[ ${wflag} -eq 1 ]] ; then
1698 print "${final_dst_ppd_path}"
1702 2) # Varying copy exists
1703 print -n "$myprog: " 1>&2
1704 gettext "differing variant of source PPD file " 1>&2
1705 gettext "already exists at\n" 1>&2
1706 gettext "${final_dst_ppd_path}\n" 1>&2
1707 status=${FAIL}
1709 *) # The PPD file was not added as a problem occurred.
1710 # Display the error message.
1711 print -n "$myprog: " 1>&2
1712 print "${final_dst_ppd_path}" 1>&2
1713 status=${FAIL}
1716 esac
1719 "${GENERATEENTRY}")
1721 # Create a cache file entry for the specified PPD file and
1722 # display it on standard out.
1724 verify_ppd_file "${srcppdpath}"
1725 if [[ $? -eq 0 ]] ; then
1726 dstdir="${ppdreppath}/${ppdlabel}/${modmanuf}"
1727 final_dst_path="${dstdir}/$(/bin/basename ${srcppdpath})"
1728 verify_ppd_location "${final_dst_path}"
1729 if [[ $? -eq 0 ]] ; then
1730 # Generate the cache file entry
1731 print "$(generate_cache_file_entry "${modmanuf}" \
1732 "${model}" "${nickn}" "${devidmfg}" "${devidmdl}" \
1733 "${final_dst_path}")"
1734 else
1735 print -n "$myprog: " 1>&2
1736 gettext "PPD file not in valid location\n" 1>&2
1737 gettext \
1738 "(<repository>/<label>/<manufacturer>/<PPD file>):\n\t${1}\n" 1>&2
1739 status=${FAIL}
1742 else
1743 print -n "$myprog: " 1>&2
1744 gettext "invalid PPD file: ${1}\n" 1>&2
1745 status=${FAIL}
1749 "${REBUILD}" | "${UPDATE}")
1750 update_msg=$(update_cache "${ppdreppath}" "${ppdlabel}")
1751 if [[ $? -ne 0 ]] ; then
1752 print -n "$myprog: " 1>&2
1753 gettext "printer information does not reflect " 1>&2
1754 gettext "the\nfollowing PPD file(s):\n" 1>&2
1755 print "${update_msg}" 1>&2
1756 status=${WARN}
1761 usage
1763 esac
1765 ppdmgr_exit ${status}