# File common/lib/symbiosis/utils.rb, line 288
    def safe_open(file, mode = File::RDONLY, opts = {}, &block)
      #
      # Make sure the mode doesn't automatically truncate the file
      #
      if mode.is_a?(String)
        raise Errno::EPERM, "Bad mode string #{mode.inspect} for opening a file safely." if %w(w w+).include?(mode)

      elsif mode.is_a?(Integer)
        raise Errno::EPERM, "Bad mode string #{mode.inspect} for opening a file safely." if (File::TRUNC == (mode & File::TRUNC))

      else
        raise ArgumentError, "Bad mode #{mode.inspect}"

      end

      #
      # set some default options
      #
      opts = {:uid => nil, :gid => nil, :mode => (0666 - File.umask)}.merge(opts)

      #
      # Set up our filehandle object.
      #
      fh = nil

      begin  
        #
        # This will raise an error if we can't open the file
        #
        fh = File.open(file, mode, opts[:mode])

        #
        # Check to see if we've opened a symlink.
        #
        link_stat = fh.lstat
        file_stat = fh.stat
  
        if link_stat.symlink? and file_stat.uid != link_stat.uid
          #
          # uh-oh .. symlink pointing at a file owned by someone else?
          #
          raise Errno::EPERM, file
        end

        #
        # Check to see if the file is writable, is a file, and opened for
        # writing.  If so, we can set uid/gid/mode.
        #
        if ( link_stat.writable? and link_stat.file? and 
           ( File::WRONLY == (fh.fcntl(Fcntl::F_GETFL) & File::WRONLY) or 
             File::RDWR == (fh.fcntl(Fcntl::F_GETFL) & File::RDWR) ) )

          #
          # Change the uid/gid as needed.
          #
          if ((opts[:uid] and file_stat.uid != opts[:uid]) or 
              (opts[:gid] and file_stat.gid != opts[:gid]))
            #
            # Change the owner if not already correct
            #
            fh.chown(opts[:uid], opts[:gid])
          end

          if opts[:mode]
            #
            # Fix any permissions.
            #
            fh.chmod(opts[:mode])
          end

        end
      rescue ArgumentError, IOError, SystemCallError => err

        fh.close unless fh.nil? or fh.closed?
        raise err
      end

      if block_given?
        begin
          #
          # Yield the block, and then close the file.
          #
          yield fh
        ensure
          #
          # Close the file, if possible.
          #
          fh.close unless fh.nil? or fh.closed?
        end
      else
        #
        # Just return the file handle.
        #
        return fh
      end
      
    end