2733 pgrep/pkill prints misleading error on missing option argument
[unleashed.git] / usr / src / cmd / itutools / pkg2du.ksh
blobeb62ce7108f887ed2ad2fcc19ea63fed86fc41ae
1 #!/bin/ksh93 -p
4 # CDDL HEADER START
6 # The contents of this file are subject to the terms of the
7 # Common Development and Distribution License (the "License").
8 # You may not use this file except in compliance with the License.
10 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 # or http://www.opensolaris.org/os/licensing.
12 # See the License for the specific language governing permissions
13 # and limitations under the License.
15 # When distributing Covered Code, include this CDDL HEADER in each
16 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 # If applicable, add the following below this CDDL HEADER, with the
18 # fields enclosed by brackets "[]" replaced with your own identifying
19 # information: Portions Copyright [yyyy] [name of copyright owner]
21 # CDDL HEADER END
24 # Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 # Use is subject to license terms.
29 # pkg2du - convert driver packages to Driver Update (DU) format
32 readonly PROG=$0
33 readonly ORIGPWD=$PWD
34 readonly TMP_DIR=${TMPDIR:-/tmp}/${PROG##*/}.$$
36 # Must-have utilities
37 readonly CPIO=/usr/bin/cpio
38 readonly GZIP=/usr/bin/gzip
39 readonly MKISOFS=/usr/bin/mkisofs
40 readonly PATCHADD=/usr/sbin/patchadd
41 readonly PKGTRANS=/usr/bin/pkgtrans
42 readonly ROOT_ARCHIVE=/usr/sbin/root_archive
43 readonly LOFIADM=/usr/sbin/lofiadm
44 readonly MKDIR=/usr/bin/mkdir
45 readonly RM=/usr/bin/rm
46 readonly CP=/usr/bin/cp
47 readonly HEAD=/usr/bin/head
48 readonly SORT=/usr/bin/sort
49 readonly MKBOOTMEDIA=/usr/bin/mkbootmedia
50 readonly PKG2DU=/usr/bin/pkg2du
51 readonly TOUCH=/usr/bin/touch
52 readonly NAWK=/usr/bin/nawk
53 readonly CHMOD=/usr/bin/chmod
54 readonly GREP=/usr/bin/grep
55 readonly LS=/usr/bin/ls
56 readonly LN=/usr/bin/ln
57 readonly SED=/usr/bin/sed
58 readonly CAT=/usr/bin/cat
59 readonly FIND=/usr/bin/find
60 readonly UNAME=/usr/bin/uname
61 readonly MACH=`$UNAME -p`
63 # for gettext
64 TEXTDOMAIN=SUNW_OST_OSCMD
65 export TEXTDOMAIN
68 function usage
70 gettext "Usage:\n${PROG##*/} -r <release> [-f] [-v] [-d <dir>] [-o <iso>] [-l <label>]\n <pkg> [<pkg> ...]\n"
71 gettext "Options:\n -d <dir>\n Directory where the Driver Update directory should be created.\n"
72 gettext " -o <iso>\n Create a Solaris ISO image of the Driver Update directory.\n"
73 gettext " -f\n If <dir>/DU or <iso> exists, remove it without asking first.\n"
74 gettext " -l <label>\n Label/volume name of the ISO image (if -o option is specified).\n"
75 gettext " -r <release>\n Solaris release number to use. It takes the form of 5.10.\n This option must be specified.\n"
76 gettext " -v\n Verbose. Multiple -v options increase verbosity.\n"
77 echo;
81 function check_prereqs
83 typeset f
85 # We must have these utilities.
86 for f in $GZIP ${ISO:+$MKISOFS} $PKGTRANS
87 do
88 if [[ ! -x "$f" ]]
89 then
90 gettext "Cannot find required utilty $f"
91 exit 1
93 done
97 function cleanup
99 $RM -rf "$TMP_DIR"
103 function is_overwrite
105 typeset arg=$1
106 typeset -l ans
108 [[ $FORCE == yes ]] && return 0
110 while true
112 gettext "$arg already exists. Overwrite it? (y/n) "
113 read ans
114 case $ans in
115 y*|Y*) return 0 ;; # go ahead overwrite
116 n*|N*) return 1 ;; # don't overwrite
117 esac
118 done
119 echo;
123 function collect_objs # <pkg> ...
125 typeset obj fail=0
127 for obj
129 if [[ -f "$obj"/pkginfo ]]
130 then
131 PACKAGES[ ${#PACKAGES[*]} ]=$obj
132 else
133 gettext "$obj is not in package format\n"
134 (( fail += 1 ))
136 done
137 (( fail )) && return 1
138 return 0
142 function mkdu
144 typeset distdir tmpdudir pkgs obj statusfile
146 trap '/bin/rm -rf $statusfile $tmpdudir' EXIT
148 # Create DU directory first.
149 distdir=$ROOTDIR/DU/sol_$VERSION/$MACH
150 $MKDIR -p "$distdir/Tools" "$distdir/Product"
152 # to the other UltraSPARC architecture
153 if [[ "$MACH" != "i386" ]]
154 then
155 cd $ROOTDIR/DU/sol_$VERSION
156 $LN -s sparc sun4v
157 $LN -s sparc sun4u
158 else
159 cd $ROOTDIR/DU/sol_$VERSION
160 $LN -s i386 i86pc
163 # Unfortunately pkgtrans insists that all packages must be in
164 # <device1> (see pkgtrans(1)). The packages can't have any path
165 # components. So we'll create a temporary directory first and then
166 # symlinks to the specified packages. Then run pkgtrans with
167 # the temporary directory as <device1>.
168 tmpdudir=$TMP_DIR/mkdu
169 $MKDIR -p "$tmpdudir"
171 for obj in "${PACKAGES[@]}"
173 # Get rid of trailing /'s, if any.
174 [[ "$obj" == */ ]] && obj=${obj%%+(/)}
176 # Make sure it's a full pathname.
177 [[ "$obj" != /* ]] && obj=$ORIGPWD/$obj
179 $LN -s "$obj" "$tmpdudir" || exit 1
181 # Remember just the file component.
182 pkgs[ ${#pkgs[*]} ]=${obj##*/}
183 done
185 # Package up packages as compressed data stream.
186 statusfile=$TMP_DIR/.pkgtrans.status
188 $PKGTRANS -s "$tmpdudir" /dev/stdout "${pkgs[@]}"
189 echo $? > $statusfile
190 $TOUCH $statusfile # make sure file is created
191 } | $GZIP -9 > "$distdir/Product/pkgs.gz"
193 [[ -s $statusfile && $(<$statusfile) != 0 ]] && return 1
195 # Create admin file for pkgadd
196 $CAT > "$distdir/Tools/admin" <<"EOF"
197 mail=
198 instance=unique
199 partial=nocheck
200 runlevel=nocheck
201 idepend=nocheck
202 rdepend=nocheck
203 space=nocheck
204 setuid=nocheck
205 conflict=nocheck
206 action=nocheck
209 # Create install.sh
210 $CAT > "$distdir/Tools/install.sh" <<"EOF"
211 #!/sbin/sh
212 # install.sh -R <basedir> - install packages to basedir
213 basedir=/
214 toolsdir=`dirname $0`
215 tmpfile=/tmp/`basename $0`.$$
216 while getopts "R:" arg
218 case "$arg" in
219 R) basedir=$OPTARG;;
220 esac
221 done
222 /usr/bin/gzip -c -d "$toolsdir/../Product/pkgs.gz" > $tmpfile &&
223 /usr/sbin/pkgadd -R "$basedir" -d "$tmpfile" -a "$toolsdir/admin" all
224 status=$?
225 /bin/rm -f "$tmpfile"
226 exit $status
228 $CHMOD a+rx "$distdir/Tools/install.sh"
232 function mkiso
234 typeset vflag
236 # Skip if no ISO image was specified.
237 [[ -z "$ISO" ]] && return 0
239 # Determine mkisofs' verbose flag depending on $VERBOSE_LEVEL.
240 case $VERBOSE_LEVEL in
241 0) vflag=-quiet
243 1) vflag= # mkisofs' default verboseness
245 *) vflag=
246 i=$VERBOSE_LEVEL
247 while ((i > 0))
249 vflag="-v $vflag"
250 (( i -= 1 ))
251 done
253 esac
255 (( VERBOSE_LEVEL )) && gettext "Creating ISO image ..."
257 # Note: the "-log-file >(cat -u >&2)" and "2>/dev/null" below is a
258 # trick to filter out mkisofs's warning message about being
259 # non-conforming to ISO-9660.
260 # We do some funky architecture-specific stuff here so that we can
261 # actually create a bootable media image for UltraSPARC systems
263 ISOARGS_sparc="-B ... -joliet-long -R -U"
264 ISOARGS_i386="-d -N -r -relaxed-filenames"
265 if [[ "$MACH" = "i386" ]]
266 then
267 ISOARGS=$ISOARGS_i386
268 else
269 ISOARGS=$ISOARGS_sparc
272 $MKISOFS -o "$ISO" \
273 -allow-leading-dots \
274 $ISOARGS \
275 -ldots -full-iso9660-filenames \
276 -R -J \
277 -V "$ISOLABEL" \
278 $vflag \
279 -log-file >($CAT -u >&2) \
280 "$ROOTDIR" 2>/dev/null
285 # Main
287 trap cleanup EXIT
289 FORCE=
290 ISO=
291 LABEL=
292 RELEASE=
293 ROOTDIR=
294 VERBOSE_LEVEL=0
296 while getopts ':d:fo:l:r:v' opt
298 case $opt in
299 d) ROOTDIR=$OPTARG
301 f) FORCE=yes
303 o) ISO=$OPTARG
304 if [ ! -z `echo $ISO | $GREP "^/tmp"` ]; then
305 gettext "ISO images will not be created on /tmp.\n"
306 gettext "Please choose a different output location.\n"
307 exit 3
310 l) LABEL=$OPTARG
312 r) RELEASE=$OPTARG
314 v) (( VERBOSE_LEVEL += 1 ))
316 :) gettext "Option -$OPTARG missing argument."
317 usage
318 exit 1
320 *) gettext "Option -$OPTARG invalid.\n"
321 usage
322 exit 2
324 esac
325 done
326 shift 'OPTIND - 1'
328 # Release number must be specified.
329 if [[ -z "$RELEASE" ]]
330 then
331 gettext "Solaris release number must be specified (-r option).\n"
332 usage
333 exit 1
336 # Verify release number. Allow major.minor or major.minor.micro format.
337 if [[ $RELEASE != +([0-9]).+([0-9])?(.+([0-9])) ]]
338 then
339 gettext "Invalid release number: $RELEASE\n"
340 exit 1
342 VERSION=$(echo $RELEASE | $SED 's/5\./2/')
344 # Either or both of -d or -o option must be specified.
345 if [[ -z "$ROOTDIR" && -z "$ISO" ]]
346 then
347 gettext "Either -d or -o option (or both) must be specified.\n"
348 usage
349 exit 1
352 # There must be at least one package.
353 if (( $# == 0 ))
354 then
355 gettext "No package was specified.\n"
356 usage
357 exit 1
360 # Check and collect packages
361 unset PACKAGES
362 collect_objs "$@" || exit 1
364 # Default label for ISO image
365 LABEL=${LABEL:-DU sol_$VERSION}
367 check_prereqs # must be called after $ISO is possibly set
369 # If an ISO image was specified, check its parent directory and get its
370 # full pathname.
371 unset ISODIR
372 if [[ -n "$ISO" ]]
373 then
374 if [[ "$ISO" = */* ]]
375 then
376 ISODIR=$(cd "${ISO%/*}" 2>/dev/null && pwd -P)
377 if (( $? ))
378 then
379 gettext "Can't access parent directory of ISO image\n"
380 exit 1
382 else
383 ISODIR=$(pwd -P)
387 # If user specified a media root directory, verify it exists, else use
388 # a temporary directory.
389 if [[ -n "$ROOTDIR" ]]
390 then
391 $MKDIR -p "$ROOTDIR";
392 if [ $? != 0 ]; then
393 gettext "$ROOTDIR is not a directory.\n"
394 exit 1
395 elif [[ ! -w "$ROOTDIR" ]] then
396 gettext "Directory $ROOTDIR is not writable.\n"
397 exit 1
399 # If an ISO image path is also specified, make sure it's not under
400 # $ROOTDIR since we're going to take the ISO image of $ROOTDIR.
401 if [[ -n "$ISODIR" ]]
402 then
403 realroot=$(cd "$ROOTDIR" 2>/dev/null && pwd -P)
404 if [[ "$ISODIR" = "$realroot"?(/*) ]]
405 then
406 gettext "ISO image must not be under Driver Update's parent directory ($realroot)\n"
407 exit 1
410 else
411 ROOTDIR=$TMP_DIR/root
414 # If DU directory already exists, ask user permission to remove it unless -f
415 # option was specified.
416 if [[ -d "$ROOTDIR/DU" ]]
417 then
418 is_overwrite "$ROOTDIR/DU" || exit 0
419 $RM -rf "$ROOTDIR/DU"
422 # If ISO image already exists, ask user permission to remove it unless -f
423 # option was specified.
424 if [[ -f "$ISO" ]]
425 then
426 is_overwrite "$ISO" || exit 0
427 $RM -f "$ISO"
430 # Create DU directory and the ISO image (if requested).
431 mkdu && mkiso
432 if (( $? ))
433 then
434 $RM -rf "$ROOTDIR/DU"
435 [[ -n "$ISO" ]] && $RM -f "$ISO"
436 exit 1
438 exit 0