#!/usr/bin/env python2.5

import sys
import os
from subprocess import call

def losetup(source, offset=0):
  # XXX we avoid colliding with other instances of ourself,
  #     but when it comes to other loop-device users we just
  #     pick a range things don't seem to use and hope...
  lockfilename = '/tmp/losetup.lock'
  os.close(os.open(lockfilename, os.O_CREAT+os.O_EXCL)) #lock
  try:
    loopdevice = None
    for i in xrange(32,60): # totally arbitrary, just looks to be unused on black-mesa
      filename = '/dev/loop%d'%i
      if 0 == len(file(filename).read(1)):
        loopdevice = filename # it's empty
        break
    if loopdevice is not None:
      call(['losetup', '-o', str(offset), loopdevice, source])
    else:
      raise RuntimeError('out of loop devices for copying VM image: too many at once?')
  finally:
    os.unlink(lockfilename) #unlock
  return loopdevice

def main(*argv):
  args = argv[1:]
  os.environ['PATH'] = '/usr/sbin:/usr/bin:/sbin:/bin'
  if not (1 <= len(args) <= 2):
    print >>sys.stderr, 'usage: %s sourcedevice [offset]' % argv[0]
    print >>sys.stderr, 'prints resulting loopback device; don\'t forget to losetup -d'
    return 2
  print losetup(*args)
  return 0

if __name__ == '__main__':
  sys.exit(main(*sys.argv))