• R/O
  • SSH
  • HTTPS

cabos: Commit


Commit MetaInfo

Revisão75 (tree)
Hora2010-01-21 20:34:44
Autorheavy_baby

Mensagem de Log

compact project

Mudança Sumário

Diff

--- trunk/Cabos/dmgutil.pl (nonexistent)
+++ trunk/Cabos/dmgutil.pl (revision 75)
@@ -0,0 +1,738 @@
1+#!/usr/bin/perl -w
2+#============================================================================
3+# NAME:
4+# dmgutil.pl
5+#
6+# DESCRIPTION:
7+# Disk image creation utility.
8+#
9+# COPYRIGHT:
10+# Copyright (c) 2006-2009, refNum Software
11+# <http://www.refnum.com/>
12+#
13+# All rights reserved.
14+#
15+# Redistribution and use in source and binary forms, with or without
16+# modification, are permitted provided that the following conditions
17+# are met:
18+#
19+# o Redistributions of source code must retain the above
20+# copyright notice, this list of conditions and the following
21+# disclaimer.
22+#
23+# o Redistributions in binary form must reproduce the above
24+# copyright notice, this list of conditions and the following
25+# disclaimer in the documentation and/or other materials
26+# provided with the distribution.
27+#
28+# o Neither the name of refNum Software nor the names of its
29+# contributors may be used to endorse or promote products derived
30+# from this software without specific prior written permission.
31+#
32+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
35+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
37+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
38+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
39+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
40+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
42+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43+#============================================================================
44+# Imports
45+#----------------------------------------------------------------------------
46+use strict;
47+use Getopt::Long;
48+
49+
50+
51+
52+
53+#============================================================================
54+# Constants
55+#----------------------------------------------------------------------------
56+my $kLogging = "-quiet";
57+
58+my $Rez = "/Developer/Tools/Rez";
59+my $SetFile = "/Developer/Tools/SetFile";
60+
61+my $kManPage = <<MANPAGE;
62+NAME
63+dmgutil -- create, adjust, and compress a distribution disk image
64+
65+SYNOPSIS
66+dmgutil --help
67+
68+dmgutil --open --volume=name file
69+
70+dmgutil --set [--x=integer] [--y=integer]
71+[--width=integer] [--height=integer]
72+[--iconsize=integer] [--icon=file]
73+[--background=file] [--bgcol=r,g,b]
74+[--toolbar=boolean] file
75+
76+dmgutil --close --volume=name [--license=file] file
77+
78+DESCRIPTION
79+dmgutil is used to create distribution disk images, and to adjust
80+the Finder view settings of these volumes or their contents.
81+
82+It can be invoked in three modes: open, set, and close.
83+
84+OPEN MODE
85+Open Mode has the following options:
86+--open Select open mode.
87+
88+--volume=name The volume name for the disk image.
89+
90+file The output path for the .dmg file.
91+
92+SET MODE
93+Set Mode has the following options:
94+--set Select set mode.
95+
96+--x=integer The x coordinate of the item.
97+
98+--y=integer The y coordinate of the item.
99+
100+--width=integer The width for a Finder window.
101+
102+--height=integer The height for a Finder window.
103+
104+--iconsize=integer The icon size for a Finder window.
105+
106+--icon=file.icns The icon to apply to the item.
107+
108+--background=file The background picture for a Finder window.
109+
110+--bgcol=r,g,b The background color for a Finder window.
111+
112+--toolbar=boolean The toolbar state for a Finder window.
113+
114+file The file or folder to be set.
115+
116+CLOSE MODE
117+Close Mode has the following options:
118+--close Select close mode.
119+
120+--volume=name The volume name for the disk image.
121+
122+--license=file The license agreement resource.
123+
124+file The output path for the .dmg file.
125+
126+EXAMPLES
127+OPEN MODE
128+To create a new disk image for "MyApp 1.0":
129+
130+dmgutil.pl --open --volume="MyApp 1.0" myapp_1.0.dmg
131+
132+SET MODE
133+To set the position of a file or folder:
134+
135+dmgutil.pl --set --x=100 --y=100 "/Volumes/MyApp 1.0/Read Me.rtf"
136+dmgutil.pl --set --x=200 --y=100 "/Volumes/MyApp 1.0/MyApp.app"
137+
138+To set the window size for the volume:
139+
140+dmgutil.pl --set --width=300 --height=200 "/Volumes/MyApp 1.0"
141+
142+To set the icon size for the volume:
143+
144+dmgutil.pl --set --iconsize=128 "/Volumes/MyApp 1.0"
145+
146+To set a custom icon for a volume, folder, or file:
147+
148+dmgutil.pl --set --icon=volume.icns "/Volumes/MyApp 1.0"
149+dmgutil.pl --set --icon=folder.icns "/Volumes/MyApp 1.0/Extras"
150+dmgutil.pl --set --icon=readme.icns "/Volumes/MyApp 1.0/Read Me.rtf"
151+
152+To set the background picture for the volume:
153+
154+dmgutil.pl --set --background=flowers.jpg "/Volumes/MyApp 1.0"
155+
156+To set the background color for the volume:
157+
158+dmgutil.pl --set --bgcol=0,65535,0 "/Volumes/MyApp 1.0"
159+
160+To hide the toolbar for the volume:
161+
162+dmgutil.pl --set --toolbar=false "/Volumes/MyApp 1.0"
163+
164+Multiple flags may be combined, to set all of the properties of an
165+item simultaneously.
166+
167+CLOSE MODE
168+To unmount and compress the disk image created for "MyApp 1.0":
169+
170+dmgutil.pl --close --volume="MyApp 1.0" myapp_1.0.dmg
171+
172+VERSION
173+dmgutil 1.1
174+
175+COPYRIGHT
176+Copyright (c) refNum Software http://www.refnum.com/
177+MANPAGE
178+
179+
180+
181+
182+
183+#============================================================================
184+# appleScript : Execute an AppleScript.
185+#----------------------------------------------------------------------------
186+sub appleScript
187+{
188+
189+
190+ # Retrieve our parameters
191+ my ($theScript) = @_;
192+
193+
194+
195+ # Save the script
196+ my $theFile = "/tmp/dmgutil_applescript.txt";
197+
198+ open( OUTPUT, ">$theFile") or die "Can't open $theFile for writing: $!\n";
199+ print OUTPUT $theScript;
200+ close(OUTPUT);
201+
202+
203+
204+ # And execute it
205+ system("osascript", $theFile);
206+ unlink($theFile);
207+}
208+
209+
210+
211+
212+
213+#============================================================================
214+# isVolume : Is a path to the root of a volume?
215+#----------------------------------------------------------------------------
216+sub isVolume
217+{
218+
219+
220+ # Retrieve our parameters
221+ my ($thePath) = @_;
222+
223+
224+
225+ # Check the state
226+ #
227+ # After stripping out the leading /Volumes, any further slashes
228+ # indicate we have a folder rather than a volume.
229+ $thePath =~ s/\/Volumes\///;
230+
231+ my $isVolume = ($thePath =~ /.*\/.*/) ? 0 : 1;
232+
233+ return($isVolume);
234+}
235+
236+
237+
238+
239+
240+#============================================================================
241+# setFolderState : Set the state for a folder.
242+#----------------------------------------------------------------------------
243+sub setFolderState
244+{
245+
246+
247+ # Retrieve our parameters
248+ my ($thePath, $iconSize, $flagToolbar, $bgImage, $bgColor) = @_;
249+
250+
251+
252+ # Initialise ourselves
253+ my $cmdBackground = "";
254+ my $cmdIconSize = "";
255+ my $cmdToolbar = "";
256+
257+
258+
259+ # Prepare the background
260+ #
261+ # As of 10.5, the Finder refuses to manipulate files whose names start with
262+ # a period (rdar://5582578). As such we need to use an underscore for the
263+ # image, then make it invisible using SetFile.
264+ if (-f $bgImage)
265+ {
266+ $bgImage =~ /.*\.(\w+)/;
267+ my $dstImage = "$thePath/_Background.$1";
268+
269+ `cp "$bgImage" "$dstImage"`;
270+
271+ $cmdBackground .= "set theImage to posix file \"$dstImage\"\n";
272+ $cmdBackground .= " set background picture of theOptions to theImage\n";
273+ $cmdBackground .= " do shell script \"/Developer/Tools/SetFile -a V '$dstImage'\"\n";
274+ }
275+
276+ elsif ($bgColor ne "")
277+ {
278+ $cmdBackground = "set background color of theOptions to {$bgColor} as RGB color";
279+ }
280+
281+
282+
283+ # Prepare the icon size
284+ if ($iconSize != 0)
285+ {
286+ $cmdIconSize = "set icon size of theOptions to $iconSize";
287+ }
288+
289+
290+
291+ # Prepare the toolbar
292+ #
293+ # The window must be made visible in order to change the toolbar state.
294+ if ($flagToolbar ne "")
295+ {
296+ $cmdToolbar = " open theWindow \n";
297+ $cmdToolbar .= " set toolbar visible of theWindow to $flagToolbar \n";
298+ $cmdToolbar .= " close theWindow \n";
299+ }
300+
301+
302+
303+ # Identify the target
304+ #
305+ # AppleScript requires the correct nomenclature for the target item.
306+ my $theTarget = "folder \"$thePath\"";
307+
308+ if (isVolume($thePath))
309+ {
310+ $theTarget =~ s/folder "\/Volumes\//disk "/;
311+ }
312+
313+
314+
315+ # Set the folder state
316+ #
317+ # Once a change has been made, it must be flushed to disk with update.
318+ my $theScript = "";
319+
320+ $theScript .= "tell application \"Finder\"\n";
321+ $theScript .= " set theTarget to $theTarget \n";
322+ $theScript .= " set theWindow to window of theTarget \n";
323+ $theScript .= "\n";
324+ $theScript .= " set current view of theWindow to icon view \n";
325+ $theScript .= " set theOptions to icon view options of theWindow \n";
326+ $theScript .= " set arrangement of theOptions to not arranged \n";
327+ $theScript .= "\n";
328+ $theScript .= " $cmdBackground\n";
329+ $theScript .= " $cmdIconSize \n";
330+ $theScript .= " $cmdToolbar \n";
331+ $theScript .= "\n";
332+ $theScript .= " update theTarget\n";
333+ $theScript .= "end tell";
334+
335+ appleScript($theScript);
336+}
337+
338+
339+
340+
341+
342+#============================================================================
343+# setCustomIcon : Set a custom icon.
344+#----------------------------------------------------------------------------
345+sub setCustomIcon
346+{
347+
348+
349+ # Retrieve our parameters
350+ my ($thePath, $theIcon) = @_;
351+
352+
353+
354+ # Validate our state
355+ #
356+ # We require several tools inside /Developer/Tools.
357+ die("Setting an icon requires $Rez") if (! -e $Rez);
358+ die("Setting an icon requires $SetFile") if (! -e $SetFile);
359+
360+
361+
362+ # Prepare the flags
363+ #
364+ # Prior to Mac OS X 10.4, SetFile can only set an attribute if it is
365+ # first cleared (rdar://3738867).
366+ my $sysVers = `uname -r`;
367+ my $setHidden = ($sysVers =~ /^[0-7]\./) ? "vV" : "V";
368+ my $setIcon = ($sysVers =~ /^[0-7]\./) ? "cC" : "C";
369+
370+
371+
372+ # Set a volume icon
373+ #
374+ # Volume custom icons are contained in a .VolumeIcon.icns file.
375+ if (isVolume($thePath))
376+ {
377+ my $iconFile = "$thePath/.VolumeIcon.icns";
378+
379+ `cp "$theIcon" "$iconFile"`;
380+
381+ `$SetFile -a $setHidden "$iconFile"`;
382+ `$SetFile -a $setIcon "$thePath"`;
383+ }
384+
385+
386+ # Set a folder icon
387+ #
388+ # Folder custom icons are contained in an ('icns', -16455) resource,
389+ # placed in an invisible "Icon\r" file inside the folder.
390+ elsif (-d $thePath)
391+ {
392+ my $iconFile = "$thePath/Icon\r";
393+ my $tmpR = "/tmp/dmgutil.r";
394+
395+ `echo "read 'icns' (-16455) \\"$theIcon\\";\n" > $tmpR`;
396+ `cd /tmp; $Rez dmgutil.r -append -o "$iconFile"`;
397+
398+ `$SetFile -a $setHidden "$iconFile"`;
399+ `$SetFile -a $setIcon "$thePath"`;
400+
401+ unlink($tmpR);
402+ }
403+
404+
405+ # Set a file icon
406+ #
407+ # File custom icons are contained in an ('icns', -16455) resource.
408+ else
409+ {
410+ my $tmpR = "/tmp/dmgutil.r";
411+
412+ `echo "read 'icns' (-16455) \\"$theIcon\\";\n" > $tmpR`;
413+ `cd /tmp; $Rez dmgutil.r -append -o "$thePath"`;
414+
415+ `$SetFile -a $setIcon "$thePath"`;
416+
417+ unlink($tmpR);
418+ }
419+}
420+
421+
422+
423+
424+
425+#============================================================================
426+# setWindowPos : Set the position of a window.
427+#----------------------------------------------------------------------------
428+sub setWindowPos
429+{
430+
431+
432+ # Retrieve our parameters
433+ my ($thePath, $posX, $posY, $theWidth, $theHeight) = @_;
434+
435+
436+
437+ # Initialise ourselves
438+ my $bottom = $posY + $theHeight;
439+ my $right = $posX + $theWidth;
440+
441+
442+
443+ # Identify the target
444+ #
445+ # AppleScript requires the correct nomenclature for the target item.
446+ my $theTarget = "folder \"$thePath\"";
447+
448+ if (isVolume($thePath))
449+ {
450+ $theTarget =~ s/folder "\/Volumes\//disk "/;
451+ }
452+
453+
454+
455+ # Set the window position
456+ #
457+ # In theory, the "set bounds" command is all that should be necessary
458+ # to set the bounds of a Finder window.
459+ #
460+ # Unfortunately, under 10.4 this will result in a window that will be
461+ # taller than the specified size when the window is next opened.
462+ #
463+ # To reliably set the bounds of a window we must open the window, show
464+ # the status bar, and set the window bounds to be 20 pixels taller (the
465+ # height of the status bar) than necessary.
466+ #
467+ # The status bar can then be hidden, the window closed, and the bounds
468+ # bounds will be the desired size when the window is next opened.
469+ my $theScript = "";
470+
471+ $theScript .= "tell application \"Finder\"\n";
472+ $theScript .= " set theTarget to $theTarget \n";
473+ $theScript .= " set theWindow to window of theTarget \n";
474+ $theScript .= "\n";
475+ $theScript .= " open theWindow \n";
476+ $theScript .= " set statusbar visible of theWindow to true \n";
477+ $theScript .= " set bounds of theWindow to {$posX, $posY, $right, $bottom+20} \n";
478+ $theScript .= " set statusbar visible of theWindow to false \n";
479+ $theScript .= " close theWindow \n";
480+ $theScript .= "\n";
481+ $theScript .= "end tell";
482+
483+ appleScript($theScript);
484+}
485+
486+
487+
488+
489+
490+#============================================================================
491+# setIconPos : Set the position of an icon.
492+#----------------------------------------------------------------------------
493+sub setIconPos
494+{
495+
496+
497+ # Retrieve our parameters
498+ my ($theFile, $posX, $posY) = @_;
499+
500+
501+
502+ # Identify the target
503+ #
504+ # Since the 'posix file' command follows symlinks, in order to set the
505+ # position of a symlink (vs its target) we need to use an HFS path and
506+ # reference it as a file rather than an alias.
507+ my $theTarget = "alias (posix file \"$theFile\")";
508+
509+ if (-l $theFile)
510+ {
511+ $theTarget = $theFile;
512+
513+ $theTarget =~ s/\/Volumes\///;
514+ $theTarget =~ s/\//:/g;
515+ $theTarget = "file \"$theTarget\"";
516+ }
517+
518+
519+
520+ # Set the icon position
521+ #
522+ # Once a change has been made, it must be flushed to disk with update.
523+ my $theScript = "";
524+
525+ $theScript .= "tell application \"Finder\"\n";
526+ $theScript .= " set theTarget to $theTarget \n";
527+ $theScript .= "\n";
528+ $theScript .= " set position of theTarget to {$posX, $posY} \n";
529+ $theScript .= " update theTarget\n";
530+ $theScript .= "end tell";
531+
532+ appleScript($theScript);
533+}
534+
535+
536+
537+
538+
539+#============================================================================
540+# doOpen : Open a new disk image.
541+#----------------------------------------------------------------------------
542+sub doOpen
543+{
544+
545+
546+ # Retrieve our parameters
547+ my ($dmgFile, $volName) = @_;
548+
549+
550+
551+ # Clean up any previous image
552+ system("rm", "-f", "$dmgFile.sparseimage");
553+ system("rm", "-f", "$dmgFile");
554+
555+
556+
557+ # Create the image
558+ #
559+ # A large sparse disk image is created, which will be shrunk down
560+ # and compressed when the disk image is finally closed.
561+ print " creating $dmgFile\n" if ($kLogging eq "-quiet");
562+
563+ system("hdiutil", "create", $dmgFile,
564+ "-volname", $volName,
565+ "-megabytes", "1000",
566+ "-type", "SPARSE",
567+ "-fs", "HFS+",
568+ $kLogging);
569+
570+ system("hdiutil", "mount", $kLogging, "$dmgFile.sparseimage");
571+}
572+
573+
574+
575+
576+
577+#============================================================================
578+# doClose : Close a disk image.
579+#----------------------------------------------------------------------------
580+sub doClose
581+{
582+
583+
584+ # Retrieve our parameters
585+ my ($dmgFile, $volName, $theLicense) = @_;
586+
587+
588+
589+ # Bless the volume
590+ #
591+ # Blessing the volume ensures that the volume always opens in the current
592+ # view, overriding the user's "Open new windows in column view" preference.
593+ system("bless", "--openfolder", "/Volumes/$volName");
594+
595+
596+
597+ # Compress the image
598+ #
599+ # On 10.5, the disk image must be ejected rather than unmounted to allow
600+ # it to be converted from a sparse image to a compressed image.
601+ print " compressing $dmgFile\n" if ($kLogging eq "-quiet");
602+
603+ system("hdiutil", "eject", $kLogging, "/Volumes/$volName");
604+
605+ if ($theLicense ne "")
606+ {
607+ system("hdiutil", "unflatten", $kLogging, "$dmgFile.sparseimage");
608+ `$Rez -a "$theLicense" -o "$dmgFile.sparseimage"`;
609+ system("hdiutil", "flatten", $kLogging, "$dmgFile.sparseimage");
610+ }
611+
612+ system("hdiutil", "convert", "$dmgFile.sparseimage",
613+ "-format", "UDZO",
614+ "-o", $dmgFile,
615+ "-imagekey", "zlib-level=9",
616+ $kLogging);
617+
618+
619+
620+ # Clean up
621+ system("rm", "-f", "$dmgFile.sparseimage");
622+}
623+
624+
625+
626+
627+
628+#============================================================================
629+# doSet : Set a file/folder state.
630+#----------------------------------------------------------------------------
631+sub doSet
632+{
633+
634+
635+ # Retrieve our parameters
636+ my ($thePath, $posX, $posY, $theWidth, $theHeight, $iconSize, $theIcon, $bgImage, $bgColor, $flagToolbar) = @_;
637+
638+
639+
640+ # Set the custom icon
641+ if ($theIcon ne "")
642+ {
643+ setCustomIcon($thePath, $theIcon);
644+ }
645+
646+
647+
648+ # Set the folder state
649+ if ($iconSize != 0 || $bgImage ne "" || $bgColor ne "" || $flagToolbar ne "")
650+ {
651+ setFolderState($thePath, $iconSize, $flagToolbar, $bgImage, $bgColor);
652+ }
653+
654+
655+
656+ # Set the position
657+ #
658+ # Window position must be set after applying the folder state.
659+ if ($posX != 0 && $posY != 0)
660+ {
661+ if ($theWidth != 0 && $theHeight != 0)
662+ {
663+ setWindowPos($thePath, $posX, $posY, $theWidth, $theHeight);
664+ }
665+ else
666+ {
667+ setIconPos($thePath, $posX, $posY);
668+ }
669+ }
670+}
671+
672+
673+
674+
675+
676+#============================================================================
677+# dmgUtil : Manipulate a disk image.
678+#----------------------------------------------------------------------------
679+sub dmgUtil
680+{
681+
682+
683+ # Retrieve our parameters
684+ my ($doOpen, $doClose, $doSet) = (0, 0, 0);
685+ my ($posX, $posY, $theWidth, $theHeight, $iconSize) = (0, 0, 0, 0, 0);
686+ my ($volName, $theIcon, $bgImage, $bgColor, $flagToolbar, $theLicense) = ("", "", "", "", "", "");
687+
688+ GetOptions( "--open+", => \$doOpen,
689+ "--close+", => \$doClose,
690+ "--set+", => \$doSet,
691+ "--volume=s", => \$volName,
692+ "--x=i", => \$posX,
693+ "--y=i", => \$posY,
694+ "--width=i", => \$theWidth,
695+ "--height=i", => \$theHeight,
696+ "--iconsize=i", => \$iconSize,
697+ "--icon=s", => \$theIcon,
698+ "--background=s", => \$bgImage,
699+ "--bgcol=s", => \$bgColor,
700+ "--toolbar=s", => \$flagToolbar,
701+ "--license=s", => \$theLicense);
702+
703+ my ($thePath) = @ARGV;
704+
705+ $thePath = "" if (!defined($thePath));
706+
707+
708+
709+ # Perform the action
710+ if ($doOpen && $thePath ne "" && $volName ne "")
711+ {
712+ doOpen($thePath, $volName);
713+ }
714+
715+ elsif ($doClose && $thePath ne "" && $volName ne "")
716+ {
717+ doClose($thePath, $volName, $theLicense);
718+ }
719+
720+ elsif ($doSet && $thePath ne "")
721+ {
722+ doSet($thePath, $posX, $posY, $theWidth, $theHeight, $iconSize, $theIcon, $bgImage, $bgColor, $flagToolbar);
723+ }
724+
725+ else
726+ {
727+ print $kManPage;
728+ }
729+}
730+
731+
732+
733+
734+
735+#============================================================================
736+# Script entry point
737+#----------------------------------------------------------------------------
738+dmgUtil();
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Show on old repository browser