#!/usr/bin/python2
# VIM declarations
# vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=python:
  #############################################################################
  #
  # Copyright (c) 2003 Dell Computer Corporation
  # All Rights Reserved.
  #
  #############################################################################
"""
"""

#
# Unit Test Status: 
#


import os
import sys
import glob
import struct
import string
import random
import commands

DISK_SIGNATURE_OFFSET = 0x1B8
DISK_SIGNATURE_SIZE = 4
DISK_SIGNATURE_FAILED = 0xffffffffL

#------------------------------------------------------------------
def getBiosDiskSignature(bios_disk_id=0x80, directory="/proc/bios/"):
    num80=hex(bios_disk_id)
    num80=num80.replace('0x','')
    filename = (directory + '/disk%s_sig' % num80)
    file = None
    disk_sig = None
    try:
        file = open(filename, "rb")
        try:
            disk_sig = long(file.readline(),16)
        except ValueError:
            pass
    finally:
        if file is not None:
            file.close()
    return disk_sig

#------------------------------------------------------------------
def findDisksWithSignature(signature, filelist=None):
    if filelist is None: filelist = []
    sigMatchList=[]
    if (signature == None):
        #Means that int 13h call failed and no boot disk was found
        return sigMatchList
        
    #this is the exception that we want getDiskSig() to throw back to us
    # if a there is a problem talking to a device
    class sigExc(Exception): pass

    for i in filelist:
        try:
            temp = getDiskSig(i, exc=sigExc("disk sig failed") )
        except (sigExc):
            continue
        if (temp == signature):
            sigMatchList.append(i)

    return sigMatchList

#------------------------------------------------------------------
def getDiskSig(filePath, exc=None):
    retval = 0
    fd = -1
    try:
        try:
            fd = os.open( filePath, os.O_EXCL | os.O_RDWR )
            os.lseek( fd, DISK_SIGNATURE_OFFSET, 0 )
            sig = os.read(fd, DISK_SIGNATURE_SIZE )
            retval = struct.unpack( "I", sig )[0]
        finally:
            if fd != -1:
                os.close(fd)
    except (IOError, OSError), e:
        if exc is not None: raise exc
        
    return retval

#------------------------------------------------------------------
def signOneDisk(fileName='/dev/null', signature=0):
    sig = struct.pack( "I", signature )
    file = None
    try:
        file = open(fileName,"r+")  #open for writing, don't truncate
        file.seek(DISK_SIGNATURE_OFFSET,0)
        file.write(sig)
    finally:
        if file is not None:
            file.close()

#------------------------------------------------------------------
def signDisks(filelist=['/dev/null'], dontUseSig=0):
    count=len(filelist)
    signatures = buildSigList(count, dontUseSig)
    num = 0
    for i in filelist:
        try:
            signOneDisk( i, signatures[num] )
        except IOError:
            pass
        num = num + 1
    return signatures

#------------------------------------------------------------------
def buildSigList(num, dontUseSig=0):
    siglist=[]
    while (num):
        while 1:
            randomNumber = random.randint(1, sys.maxint-1)
            
            # don't reuse old sig
            if randomNumber == dontUseSig:
                continue
                
            #make sure that we don't do any dups
            # no real good way to get this to 100% in code coverage.
            for i in siglist:
                if randomNumber == i:
                       continue # try again, this is a dup number
                       
            # all checks passed, probably a good number to use    
            break
            
        siglist.append(randomNumber)
        num = num -1
    return siglist


