~gabrieljoel/auto-ndiswrapper/KDE4-GUI

« back to all changes in this revision

Viewing changes to auto-ndis.py

  • Committer: Gabriel
  • Date: 2009-01-07 01:48:40 UTC
  • Revision ID: climatewarrior@climatewarrior-blade-20090107014840-8xqmtljsie6hwx0a
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
 
 
3
#Auto-NDISwrapper by Nils Schulupp, Gabriel J. Perez and Richard Kaufman
 
4
#
 
5
#This program automatically looks at what Wi-Fi card you have, it disables any wireless driver currently installed, fetches #the correct Windows driver from the Internet and installs it with NDISwrapper.
 
6
 
 
7
#Copyright (C) 2007, 2008 Gabriel J. Perez <gabrieljoel@gmail.com>, Nils Schulupp <nils.schlupp@gmail.com> and Richard Kaufman <richardbkaufman@gmail.com>
 
8
#
 
9
#This program is free software; you can redistribute it and/or modify
 
10
#it under the terms of the GNU General Public License as published by
 
11
#the Free Software Foundation; either version 2 of the License, or
 
12
#(at your option) any later version.
 
13
#
 
14
#This program is distributed in the hope that it will be useful,
 
15
#but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
#GNU General Public License for more details.
 
18
#
 
19
#You should have received a copy of the GNU General Public License
 
20
#along with this program; if not, write to the Free Software
 
21
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
22
 
 
23
"""Auto-NDISwrapper -- Linux Wi-Fi as easy as it can get"""
 
24
 
 
25
__version__ = '0.1'
 
26
 
 
27
import os, platform, sys, re, subprocess, webbrowser, commands
 
28
from database import data
 
29
from ConfigParser import ConfigParser
 
30
from optparse import OptionParser
 
31
 
 
32
sys.path.append(os.getcwd())
 
33
 
 
34
print 'Auto-NDISwrapper %s' % (__version__, )
 
35
print 'Please remember to always try to use the latest version of NDISwrapper with this script'
 
36
 
 
37
##Parse options
 
38
parser = OptionParser(version='version: '+__version__)
 
39
parser.add_option('--ndiswrapper-bin', default='/usr/sbin/ndiswrapper', help='default: %default', metavar='FILE')
 
40
parser.add_option('-t', '--tmp-dir', default='/tmp/auto-ndis', help='default: %default', metavar='DIR')
 
41
parser.add_option('-a', '--ask', action='store_true', default=False, help='ask for confirmation')
 
42
parser.add_option('-q', '--quiet', action='store_true', default=False, help='reduce some output')
 
43
parser.add_option('--nocheck', action='store_true', default=False, help='doesn\'t check for ndiswrapper binary (debug only)')
 
44
parser.add_option('-d', '--debug', action='store_true', default=False, help='turn on debugging output')
 
45
parser.add_option('-m', '--manual', action='store_true', default=False, help='proceed with manual procedure')
 
46
opts, args = parser.parse_args()
 
47
 
 
48
##If the user isn't root the program will quit
 
49
if os.geteuid() != 0:
 
50
        print '[ERROR] You must be root to run this script'
 
51
        print 'Try, "su then python auto-ndis.py" or "sudo python auto-ndis.py"'
 
52
        sys.exit(1)
 
53
 
 
54
##If the user doesn't have ndiswrapper installed the program will quit
 
55
if not os.path.exists(opts.ndiswrapper_bin) and not opts.nocheck:
 
56
        print '[ERROR] NDISwrapper not found!!!'
 
57
        print 'Please look for "ndiswrapper" in your distribution\'s package manager and install it or go to www.ndiswrapper.com and download the latest sources'
 
58
        sys.exit(1)
 
59
 
 
60
##Print the debug options enabled
 
61
if (opts.debug):
 
62
        print '[DEBUG] Options:'
 
63
        print opts
 
64
        print '[DEBUG] Arguments:'
 
65
        print args
 
66
        print
 
67
 
 
68
def getoutput(*cmd):
 
69
        """
 
70
        Like commands.getoutput, but uses subprocess. It also returns the return code of the process.
 
71
        """
 
72
 
 
73
        myproc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
 
74
        value  =  myproc.stdout.read()
 
75
        retcode = myproc.wait()
 
76
        return value, retcode
 
77
 
 
78
def get_print_card_info():
 
79
        """
 
80
        Prints the pci id and other information about the pci wireless cards.
 
81
        """
 
82
 
 
83
        output, retcode = getoutput('lspci')
 
84
        lines = output.split('\n')
 
85
 
 
86
        for line in lines:
 
87
                if 'Network controller' in line:
 
88
                        card_data = line
 
89
                        break
 
90
 
 
91
        if card_data:
 
92
                card_info = card_data[28:len(card_data)]
 
93
                print card_info
 
94
        else:
 
95
                print 'No Network Devices Found!'
 
96
 
 
97
def check_for_internet():
 
98
        """
 
99
        Pings google to see if the user has an internet conecction available.
 
100
        """
 
101
 
 
102
        print '\n[*] Looking if an Internet connection is available, this may take a few seconds'
 
103
 
 
104
        test, retcode = getoutput('ping', '-c', '1', 'google.com')
 
105
 
 
106
        if 'unknown host' in test:
 
107
                print '[ERROR] An Internet connection was not found'
 
108
                choice = raw_input('(C)ontinue, (R)etry, (O)ffline mode or (E)xit: ')
 
109
 
 
110
                if choice == 'C' or choice == 'c':
 
111
                        pass
 
112
 
 
113
                elif choice == 'R' or choice == 'r':
 
114
                        return check_for_internet()
 
115
 
 
116
                elif choice == 'O' or choice == 'o':
 
117
                        manualmode()
 
118
                        installdriver()
 
119
                        installation_report()
 
120
                        sys.exit(1)
 
121
 
 
122
                elif choice == 'E' or choice == 'e':
 
123
                        sys.exit(1)
 
124
 
 
125
                else:
 
126
                        return check_for_internet()
 
127
 
 
128
        else:
 
129
                print '[*] Internet connection found, continuing installation'
 
130
 
 
131
def searchcard(devices_list, database):
 
132
        """
 
133
        Looks if one of the ids in the devices list given as argument matches an entry in the database given as argument.
 
134
        """
 
135
 
 
136
        for item in devices_list:
 
137
                if item in database:
 
138
                        return item
 
139
                        break
 
140
        return 'empty'
 
141
 
 
142
def remove_old_drivers():
 
143
        """
 
144
        Removes existing wireless drivers.
 
145
        """
 
146
 
 
147
        print '[*] Removing Old Drivers:'
 
148
        baddrivers = yourcard_dic['blacklist']
 
149
        if baddrivers in getoutput('lsmod| awk "{print $1}"'):
 
150
                print '   removing %s' % (baddrivers, )
 
151
                subprocess.call(['rmmod', baddrivers])
 
152
        else:
 
153
                print '   Drivers not loaded, nothing to remove'
 
154
 
 
155
def blacklist_drivers():
 
156
        """
 
157
        Blacklists existing wireless drivers.
 
158
        """
 
159
 
 
160
        print '[*] Blacklisting:'
 
161
        baddrivers = yourcard_dic['blacklist']
 
162
 
 
163
        if any(baddrivers in line.split('#')[0] for line in open('/etc/modprobe.d/blacklist')):
 
164
                print '   driver already blacklisted, skipping'
 
165
        else:
 
166
                print '   writing to /etc/modprobe.d/blacklist'
 
167
                blacklist = open('/etc/modprobe.d/blacklist', 'a')
 
168
                blacklist.write('\n#%s' % (baddrivers, ))
 
169
                blacklist.close()
 
170
 
 
171
def print_driver_license():
 
172
        """
 
173
        Checks if the user agrees with the driver's EULA.
 
174
        """
 
175
 
 
176
        print 'Do you agree with this proprietary driver\'s End User License Agreement? You can find it in the website of your card\'s manufacturer.'
 
177
        choice = raw_input('(Y)es or (N)o, if you don\'t agree the program will quit: ')
 
178
 
 
179
        if choice == 'Y' or choice == 'y':
 
180
                pass
 
181
 
 
182
        elif choice == 'N' or choice == 'n':
 
183
                sys.exit(1)
 
184
 
 
185
        else:
 
186
                return driver_license()
 
187
 
 
188
def create_auto_ndis_folder():
 
189
        """
 
190
        Creates a folder in which place the downloaded drivers.
 
191
        """
 
192
 
 
193
        try:
 
194
                os.makedirs('%s/%s' % (opts.tmp_dir, card_id, ))
 
195
                print 'Tmpdir created'
 
196
                os.chmod(opts.tmp_dir,0777)
 
197
                os.chdir('%s/%s' % (opts.tmp_dir, card_id, ))
 
198
        except:
 
199
                if os.path.exists('%s/%s' % (opts.tmp_dir, card_id, )):
 
200
                        print '\nTmpdir exists and ok, continuing'
 
201
                        os.chdir('%s/%s' % (opts.tmp_dir, card_id, ))
 
202
                else:
 
203
                        print '[ERROR] can\'t create tmpdir'
 
204
                        print '   Either specify an alternative or ensure that /tmp is writable and not full'
 
205
                        sys.exit(1)
 
206
 
 
207
def find_decompression():
 
208
        """
 
209
        Determines the right decompression program to be used with the downloaded driver.
 
210
        """
 
211
 
 
212
        decompression = 'manual'
 
213
 
 
214
        if '.exe' in url or '.zip' in url:
 
215
                decompression = 'unzip'
 
216
 
 
217
        elif '.tar' in url:
 
218
                decompression = 'tar -vvf'
 
219
 
 
220
        elif '.tar.gz' in url:
 
221
                decompression = 'tar -xvvzf'
 
222
 
 
223
        elif '.tar.bz2' in url:
 
224
                decompression = 'tar -xvvjf'
 
225
 
 
226
        elif '.cab' in url:
 
227
                decompression = 'cabextract'
 
228
 
 
229
        elif '.rar' in url:
 
230
                decompression = 'unrar'
 
231
 
 
232
        if decompression != 'manual':
 
233
                #Checks if the system has the necessary decompression program
 
234
                test = commands.getoutput(decompression)
 
235
                if 'not found' in test:
 
236
                        print '[ERROR] The program to extract %s files is not installed in your system' % (decompression, )
 
237
                        print 'Install a program on your system to extract %s files and then rerun the script' %(decompression, )
 
238
                        sys.exit(1)
 
239
        return decompression
 
240
 
 
241
def fetch():
 
242
        """
 
243
        Downloads the apropiate driver.
 
244
        """
 
245
 
 
246
        print '[*] Downloading driver now from "%s"' % (url, )
 
247
        if (opts.quiet):
 
248
                retcode = subprocess.call(['wget', url, '-qO ', opts.tmp_dir + '/' + card_id + '/' + driver, '-o ', opts.tmp_dir + '/' + card_id + '/' + 'wget.log'])
 
249
        else:
 
250
                retcode = subprocess.call(['wget', url, '-O ', opts.tmp_dir + '/' + card_id + '/' + driver, '-o ', opts.tmp_dir + '/' + card_id + '/' + 'wget.log'])
 
251
 
 
252
 
 
253
        if retcode != 0:
 
254
                print '[ERROR] Download unsuccessfull, please check your Internet conecction and wget.log in your tmpdir for errors.'
 
255
                if (opts.debug):
 
256
                        print '[DEBUG] wget returned code: %s' % (retcode, )
 
257
                sys.exit(1)
 
258
 
 
259
def extract(decompression):
 
260
        """
 
261
        Extracts the dowloaded driver.
 
262
        """
 
263
 
 
264
        print '[*] Extracting driver'
 
265
 
 
266
        if (opts.debug):
 
267
                print '[DEBUG] Decompression method: %s' % (decompression, )
 
268
 
 
269
        retcode = subprocess.call([decompression, opts.tmp_dir + '/' + card_id + '/' + driver])
 
270
 
 
271
        if retcode != 0:
 
272
                print '[WARNING] Decompression may have failed'
 
273
 
 
274
                if (opts.debug):
 
275
                        print '[DEBUG] Decompression method returned code: %s' % (retcode, )
 
276
 
 
277
                choice = raw_input('(C)ontinue, (R)etry, (S)pecify different decompression method or (E)xit: ')
 
278
 
 
279
                if choice == 'C' or choice == 'c':
 
280
                        pass
 
281
 
 
282
                elif choice == 'R' or choice == 'r':
 
283
                        return extract(decompression)
 
284
 
 
285
                elif choice == 'S' or choice == 's':
 
286
                        divided_url = url.split('.')
 
287
                        file_type = divided_url[len(divided_url)-1]
 
288
                        decompression = raw_input('Enter command to decompress %s files: ' % (file_type, ))
 
289
                        return extract(decompression)
 
290
 
 
291
                elif choice == 'E' or choice == 'e':
 
292
                        sys.exit(1)
 
293
 
 
294
                else:
 
295
                        return extract(decompression)
 
296
 
 
297
def manualmode():
 
298
        """
 
299
        Comes into play if the user doesn't have an internet connection or if the driver need to be fetched manually.
 
300
        """
 
301
 
 
302
        print '\nThe driver needs to be fetched manually from: %s' % (url, )
 
303
        print 'Please place the "%s" file, along with the .sys files into:' % (driver, )
 
304
        print '%s/%s' % (opts.tmp_dir, card_id, )
 
305
        webbrowser.open_new(url)
 
306
 
 
307
        while not any(driver in line for line in os.listdir('%s/%s/' % (opts.tmp_dir, card_id, ))):
 
308
                try:
 
309
                        dummy = raw_input('When you have succesfully dowloaded the driver and extracted it press <Enter>: ')
 
310
 
 
311
                except:
 
312
                        ##Executed when CTRL + C is pressed.
 
313
                        print '\n\nCanceled!\n'
 
314
                        sys.exit(1)
 
315
 
 
316
        print '\nDriver file found! Continuing installation.'
 
317
 
 
318
def installdriver():
 
319
        """
 
320
        Installs the driver with NDISwrapper.
 
321
        """
 
322
 
 
323
        if driver == '.inf':
 
324
                inf_files, retcode = getoutput('find', opts.tmp_dir + '/' + card_id, '-type', 'f', '-name', '*.inf')
 
325
                inf_files = inf_files.split('\n')
 
326
                inf_file = inf_files[0]
 
327
                print '\nA driver has not been specified yet for this card, will attempt procedure with the first found driver in %s/%s: %s' % (opts.tmp_dir, card_id, inf_file)
 
328
 
 
329
        else:
 
330
                inf_file, retcode = getoutput('find', opts.tmp_dir + '/' + card_id, '-type', 'f', '-name', driver)
 
331
 
 
332
        create_log_file(inf_file)
 
333
 
 
334
        if ( opts.debug ):
 
335
                print '[DEBUG] Driver found at %s' % (inf_file, )
 
336
 
 
337
        #Attempt to install driver
 
338
        output, retcode = getoutput('ndiswrapper', '-i', inf_file)
 
339
 
 
340
        #Attempt to detect errors
 
341
        if 'already' in output:
 
342
                print '\nDriver is already installed'
 
343
                pass
 
344
 
 
345
        elif retcode != 0:
 
346
                print '[ERROR] Driver installation failed'
 
347
                if (opts.debug):
 
348
                        print '[DEBUG] NDISwrapper returned code: %s' % (retcode, )
 
349
                pass
 
350
 
 
351
        else:
 
352
                ##Assume driver installed successfully and then set up and reload the module
 
353
                subprocess.call(['ndiswrapper',  '-ma'])
 
354
                subprocess.call(['modprobe', '-r', 'ndiswrapper'])
 
355
                subprocess.call(['modprobe', 'ndiswrapper'])
 
356
                print 'Installation finished'
 
357
                pass
 
358
 
 
359
def create_log_file(driver):
 
360
        """
 
361
        Creates a simple log file with some useful info.
 
362
        """
 
363
 
 
364
        log = open('autondis-log.txt', 'w')
 
365
 
 
366
        os_info = os.uname()
 
367
        distribution = platform.dist()
 
368
        ndis_version, retcode = getoutput('ndiswrapper', '-v')
 
369
 
 
370
        log.write('OS and date = ')
 
371
        for item in os_info:
 
372
                log.write(item)
 
373
 
 
374
        log.write('\nDistribution = ')
 
375
        for item in distribution:
 
376
                log.write(item)
 
377
 
 
378
        log.write('\nNDISwrapper info = ')
 
379
 
 
380
        for item in ndis_version:
 
381
                log.write(item)
 
382
 
 
383
        log.write('\nID = %s \n' % (card_id, ))
 
384
        log.write('URL = %s \n' % (url, ))
 
385
        log.write('DRIVER = %s \n' % (driver, ))
 
386
 
 
387
        log.close()
 
388
 
 
389
def get_card_id():
 
390
        """
 
391
        Gets the wireless card's id number and revision number.
 
392
        """
 
393
 
 
394
        ##Gets the id of all the pci devices
 
395
        outtext, retcode = getoutput('lspci', '-n')
 
396
 
 
397
        ##Stores the pci ids with the revision number in a list
 
398
        pci = re.findall('.{4}:.{4}\ \(rev .{2}\)',outtext)
 
399
 
 
400
        ##Gets the id of all the usb devices
 
401
        outtext2, retcode = getoutput('lsusb')
 
402
        ##Stores the usb ids in a list
 
403
        usb = re.findall('.{4}:.{4}',outtext2)
 
404
 
 
405
        pcicard = searchcard(pci, data)
 
406
        usbcard = searchcard(usb, data)
 
407
 
 
408
        ##Checks if the user has a pci card or a usb card, if he has both the program will ask card he wants to setup
 
409
        ##If he has neither the program will exit and tell him what pci card he has if he has one
 
410
        if pcicard != 'empty' and usbcard == 'empty':
 
411
                return pcicard
 
412
 
 
413
        elif pcicard == 'empty' and usbcard != 'empty':
 
414
                return usbcard
 
415
 
 
416
        elif pcicard != 'empty' and usbcard != 'empty':
 
417
                choice = raw_input('Setup (w)ificard or setup your (u)sbcard?: ')
 
418
 
 
419
                while choice != 'W' and choice != 'w' and choice != 'U' and choice != 'u':
 
420
                        print 'Please try again'
 
421
                        choice = raw_input('Setup (w)ificard or setup your (u)sbcard?: ')
 
422
                if choice == 'W' or choice == 'w':
 
423
                        return pcicard
 
424
                elif choice == 'U' or choice == 'u':
 
425
                        return usbcard
 
426
                else:
 
427
                        return get_card_id()
 
428
 
 
429
        elif pcicard == 'empty' and usbcard == 'empty':
 
430
                print 'Sorry, card not yet supported by Auto-NDISwrapper'
 
431
                print 'Save this output as it will help other people give you support'
 
432
                get_print_card_info()
 
433
                sys.exit(1)
 
434
 
 
435
def installation_report():
 
436
        """
 
437
        Prompts the user to report the installation if it was succesful.
 
438
        """
 
439
 
 
440
        output, retcode = getoutput('ndiswrapper', '-l')
 
441
        print '\n' + 'NDISwrapper output: ' + '\n' + output
 
442
 
 
443
        print 'Is your wireless connection working now with NDISwrapper thanks to this script?'
 
444
        choice = raw_input('(Y)es and I would like to help this project by reporting my installation manually trough www.easylinuxwifi.org, (N)o it did not work for me: ')
 
445
 
 
446
        if choice == 'Y' or choice == 'y':
 
447
                print '\nPlease when you have time visit www.easylinuxwifi.org and report your installation. All the information needed for the report is available in your computer in %s/%s/autondis-log.txt\nThank You!' % (opts.tmp_dir, card_id )
 
448
                sys.exit(1)
 
449
 
 
450
        elif choice == 'N' or choice == 'n':
 
451
                print '\nWe are sorry that the procedure failed, but don\'t get discouraged! Please visit easylinuxwifi.org for help or any other community support website. Remember, the community is here to help. You may also want to try with other .inf files if more than one was included in the dowloaded driver. You may do this by entering manual mode with -m flag. and removing all .inf files from %s/%s/ except the one you want to try to install. Also if possible report any broken urls as bugs in our bug tracker.' % (opts.tmp_dir, card_id)
 
452
                sys.exit(1)
 
453
 
 
454
        else:
 
455
                return installation_report()
 
456
 
 
457
##Global variables
 
458
card_id = get_card_id()
 
459
yourcard_dic = data[card_id]
 
460
url = yourcard_dic['url']
 
461
driver = yourcard_dic['driver']
 
462
decompression = find_decompression()
 
463
 
 
464
print '\n[*] Card Supported'
 
465
try:
 
466
        print '[*] Card detected as a %s' % (yourcard_dic['name'], )
 
467
try:
 
468
        print '[*] Card ciptset detected as a %s' % (yourcard_dic['chipset'], )
 
469
try:
 
470
        print '[*] Aditional comments were provided:\n"%s"' % (yourcard_dic['other']
 
471
print '[*] Will attempt to fetch and install driver for the card with id: %s' % (card_id, )
 
472
print '[*] Will attempt to fetch driver from: %s' % (url, )
 
473
print '[*] Will attempt to install driver: %s' % (driver, )
 
474
 
 
475
if (opts.ask):
 
476
        print '   Do you want to continue?'
 
477
        try:
 
478
                dummy = raw_input('   Please hit <Enter> to continue, or use Ctrl+C to cancel: ')
 
479
        except:
 
480
                print '\n\nCanceled!\n'
 
481
                sys.exit(1)
 
482
        print
 
483
 
 
484
print '[*] Beginning Setup Procedure:\n'
 
485
 
 
486
print_driver_license()
 
487
create_auto_ndis_folder()
 
488
 
 
489
if decompression != 'manual' and not (opts.manual):
 
490
        check_for_internet()
 
491
        fetch()
 
492
        extract(decompression)
 
493
        installdriver()
 
494
        installation_report()
 
495
else:
 
496
        manualmode()
 
497
        installdriver()
 
498
        installation_report()