5da5fcdf657adab7c593a36eb7b48a75609656e7
[bootmanager.git] / source / utils.py
1 # Copyright (c) 2003 Intel Corporation
2 # All rights reserved.
3
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met:
7
8 #     * Redistributions of source code must retain the above copyright
9 #       notice, this list of conditions and the following disclaimer.
10
11 #     * Redistributions in binary form must reproduce the above
12 #       copyright notice, this list of conditions and the following
13 #       disclaimer in the documentation and/or other materials provided
14 #       with the distribution.
15
16 #     * Neither the name of the Intel Corporation nor the names of its
17 #       contributors may be used to endorse or promote products derived
18 #       from this software without specific prior written permission.
19
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
24 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 # EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
33 # YOUR JURISDICTION. It is licensee's responsibility to comply with any
34 # export regulations applicable in licensee's jurisdiction. Under
35 # CURRENT (May 2000) U.S. export regulations this software is eligible
36 # for export from the U.S. and can be downloaded by or otherwise
37 # exported or reexported worldwide EXCEPT to U.S. embargoed destinations
38 # which include Cuba, Iraq, Libya, North Korea, Iran, Syria, Sudan,
39 # Afghanistan and any other country to which the U.S. has embargoed
40 # goods and services.
41
42
43 import os, sys, shutil
44 import popen2
45 import socket
46 import fcntl
47 import string
48 import exceptions
49
50 from Exceptions import *
51
52
53 def makedirs( path ):
54     """
55     from python docs for os.makedirs:
56     Throws an error exception if the leaf directory
57     already exists or cannot be created.
58
59     That is real useful. Instead, we'll create the directory, then use a
60     separate function to test for its existance.
61
62     Return 1 if the directory exists and/or has been created, a BootManagerException
63     otherwise. Does not test the writability of said directory.
64     """
65     try:
66         os.makedirs( path )
67     except OSError:
68         pass
69     try:
70         os.listdir( path )
71     except OSError:
72         raise BootManagerException, "Unable to create directory tree: %s" % path
73     
74     return 1
75
76
77
78 def removedir( path ):
79     """
80     remove a directory tree, return 1 if successful, a BootManagerException
81     if failure.
82     """
83     try:
84         os.listdir( path )
85     except OSError:
86         return 1
87
88     try:
89         shutil.rmtree( path )
90     except OSError, desc:
91         raise BootManagerException, "Unable to remove directory tree: %s" % path
92     
93     return 1
94
95
96
97 def sysexec( cmd, log= None ):
98     """
99     execute a system command, output the results to the logger
100     if log <> None
101
102     return 1 if command completed (return code of non-zero),
103     0 if failed. A BootManagerException is raised if the command
104     was unable to execute or was interrupted by the user with Ctrl+C
105     """
106     prog= popen2.Popen4( cmd, 0 )
107     if prog is None:
108         raise BootManagerException, \
109               "Unable to create instance of popen2.Popen3 " \
110               "for command: %s" % cmd
111
112     if log is not None:
113         try:
114             for line in prog.fromchild:
115                 log.write( line )
116         except KeyboardInterrupt:
117             raise BootManagerException, "Interrupted by user"
118
119     returncode= prog.wait()
120     if returncode != 0:
121         raise BootManagerException, "Running %s failed (rc=%d)" % (cmd,returncode)
122
123     prog= None
124     return 1
125
126
127 def sysexec_noerr( cmd, log= None ):
128     """
129     same as sysexec, but capture boot manager exceptions
130     """
131     try:
132         rc= 0
133         rc= sysexec( cmd, log )
134     except BootManagerException, e:
135         pass
136
137     return rc
138
139
140
141 def chdir( dir ):
142     """
143     change to a directory, return 1 if successful, a BootManagerException if failure
144     """
145     try:
146         os.chdir( dir )
147     except OSError:
148         raise BootManagerException, "Unable to change to directory: %s" % dir
149
150     return 1
151
152
153
154 def removefile( filepath ):
155     """
156     removes a file, return 1 if successful, 0 if failure
157     """
158     try:
159         os.remove( filepath )
160     except OSError:
161         raise BootManagerException, "Unable to remove file: %s" % filepath
162
163     return 1
164
165
166
167 # from: http://forums.devshed.com/archive/t-51149/
168 #              Ethernet-card-address-Through-Python-or-C
169
170 def hexy(n):
171     return "%02x" % (ord(n))
172
173 def get_mac_from_interface(ifname):
174     """
175     given a device name, like eth0, return its mac_address.
176     return None if the device doesn't exist.
177     """
178     
179     SIOCGIFHWADDR = 0x8927 # magic number
180
181     s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
182     ifname = string.strip(ifname)
183     ifr = ifname + '\0'*(32-len(ifname))
184
185     try:
186         r= fcntl.ioctl(s.fileno(),SIOCGIFHWADDR,ifr)
187         addr = map(hexy,r[18:24])
188         ret = (':'.join(map(str, addr)))
189     except IOError, e:
190         ret = None
191         
192     return ret
193