Apple Basket

(*
AppleBasket 1.0

Creates a common volume for all users.

Motivation for the script was to have a folder for common use, with read and write privileges for every user.
Tested with Mac OS X 10.4., 10.5 and 10.6. Requires launchd (appeared in Mac OS X 10.4).
Tuomas Rosberg 2010. Paste into a new document in AppleScript Editor, run from there or save as an application.
*)

-- To install or to uninstall:
tell application "System Events"
  set pListList to every item in folder "/Library/LaunchAgents/" whose name contains "AppleBasket"
  if pListList is not {} then
    set sList to {}
    repeat with i in pListList
      set s to POSIX path of i
      set sList to sList & s
    end repeat
    my Choices(sList)
  else -- pListList was empty.
    my CreateImage()
  end if
end tell
on Choices(sList)
  display dialog ¬
    "A job by this script already exists. Do You want to uninstall the job or proceed to new one?" buttons {"Uninstall", "Proceed"} default button "Uninstall"
  set theResult to button returned of the result
  if theResult is "Uninstall" then
    do shell script "sudo launchctl unload /Library/LaunchAgents/" with administrator privileges
    repeat with i in sList
      do shell script "sudo rm -f " & i with administrator privileges
    end repeat
    display dialog ¬
      "“AppleBasket” job has been uninstalled. Please log out and in." buttons "Quit" default button 1
  else -- the result is "Proceed".
    my CreateImage()
  end if
end Choices

-- Installing:
on CreateImage()
  -- To compile a unique name for the common volume:
  tell application "System Events"
    set aList to every item in folder "/" whose name contains "AppleBasket"
    set aList to aList & (every item in folder "/Users/" whose name contains "AppleBasket") -- In case of this script being used before.
  end tell
  set n to count aList
  if n is 0 then
    set n to ""
  end if
  set imageName to "AppleBasket" & n as text
  -- Info for the user:  
  display dialog ¬
    "The script will create “AppleBasket”, a common volume, readable and writable for every user, in directory /Users." & return & return & ¬
    "Next you will be asked for a password. Every user of the volume needs to enter it. (Only once if they save it in their Keychain.)" buttons {"Cancel", "OK"} default button "OK" with icon note
  if button returned of result is "OK" then
    display dialog ¬
      "Please give a password used for accessing “AppleBasket”. " default answer "Common Volume" buttons "OK" default button "OK"
    set pWord to text returned of the result
    display dialog ¬
      "The password for “AppleBasket” is “" & pWord & "”" & return & return & ¬
      "Write it down to help your memory!" buttons "OK" default button "OK" with icon note
    display dialog "To create common volume for every user you will be asked to authenticate as an administrator." & return & return & ¬
      "Create disk image " & imageName & "?" buttons {"Cancel", "OK"} default button "OK" with icon caution
    -- Action: Create an image of 1 GB volume owned by root:
    do shell script "sudo printf \"" & pWord & "\\0\" | hdiutil create -volname \"" & imageName & "\" -size 1g -type SPARSE -fs HFS+J -encryption AES-128 -stdinpass \"" & imageName & "\"" with administrator privileges
    tell application "Finder"
      activate
      set fileName to imageName & ".sparseimage"
      if (exists of file fileName of startup disk) is true then -- this tests success of previous "do shell script", may be too abundant.
        my MountCommands(fileName)
      end if
    end tell
  end if
end CreateImage

on MountCommands(fileName)
  -- Move the disk image:
  do shell script "mv -nv '" & fileName & "' /Users/" with administrator privileges
  -- Give disk image read and write permission for all users:
  do shell script "chmod 777 '/Users/" & fileName & "'" with administrator privileges
  -- Ready to write a preference list:
  set homeFolder to path to home folder as string
  set plistName to "org.AppleBasket.mount.plist"
  set newPlist to homeFolder & plistName -- A path string
  open for access newPlist with write permission -- Creates a new file, if it doesn't exist.
  set f to result
  write "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<dict>
  <key>Label</key>
  <string>org.AppleBasket.mount</string>
  <key>OnDemand</key>
  <true/>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/bin/hdiutil</string>
    <string>attach</string>
    <string>/Users/" & fileName & "</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>WatchPaths</key>
  <array>
    <string>/Volumes/</string>
  </array>
</dict>
</plist>" to f
  close access f
  -- The administrator stuff to make the job work:
  set newPlist to POSIX path of newPlist
  -- Unload launchd jobs of /Library:
  try
    do shell script "launchctl unload /Library/LaunchAgents/" with administrator privileges
  end try
  -- Move the plist to a folder watched by the system starter, launchd:
  do shell script "mv -f " & newPlist & " /Library/LaunchAgents/" with administrator privileges
  -- Change ownership of the plist to system and group to admin:
  do shell script "chown root:admin /Library/LaunchAgents/" & plistName with administrator privileges
  -- Change mode of file to read for all, execute for none:
  do shell script "chmod 644 /Library/LaunchAgents/" & plistName with administrator privileges
  -- Load launchd jobs of /Library:
  do shell script "launchctl load /Library/LaunchAgents/" with administrator privileges
  activate me
  display dialog "A per-user job for every user has been installed to mount of the common volume automatically. Please log out and in." buttons "Quit" default button 1
end MountCommands