3
#Auto-NDISwrapper by Nils Schulupp, Gabriel J. Perez and Richard Kaufman
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.
7
#Copyright (C) 2007, 2008 Gabriel J. Perez <gabrieljoel@gmail.com>, Nils Schulupp <nils.schlupp@gmail.com> and Richard Kaufman <richardbkaufman@gmail.com>
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.
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.
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
23
"""Auto-NDISwrapper -- Linux Wi-Fi as easy as it can get"""
27
import os, platform, sys, re, subprocess, webbrowser, commands
28
from database import data
29
from ConfigParser import ConfigParser
30
from optparse import OptionParser
32
sys.path.append(os.getcwd())
34
print 'Auto-NDISwrapper %s' % (__version__, )
35
print 'Please remember to always try to use the latest version of NDISwrapper with this script'
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()
48
##If the user isn't root the program will quit
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"'
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'
60
##Print the debug options enabled
62
print '[DEBUG] Options:'
64
print '[DEBUG] Arguments:'
70
Like commands.getoutput, but uses subprocess. It also returns the return code of the process.
73
myproc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
74
value = myproc.stdout.read()
75
retcode = myproc.wait()
78
def get_print_card_info():
80
Prints the pci id and other information about the pci wireless cards.
83
output, retcode = getoutput('lspci')
84
lines = output.split('\n')
87
if 'Network controller' in line:
92
card_info = card_data[28:len(card_data)]
95
print 'No Network Devices Found!'
97
def check_for_internet():
99
Pings google to see if the user has an internet conecction available.
102
print '\n[*] Looking if an Internet connection is available, this may take a few seconds'
104
test, retcode = getoutput('ping', '-c', '1', 'google.com')
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: ')
110
if choice == 'C' or choice == 'c':
113
elif choice == 'R' or choice == 'r':
114
return check_for_internet()
116
elif choice == 'O' or choice == 'o':
119
installation_report()
122
elif choice == 'E' or choice == 'e':
126
return check_for_internet()
129
print '[*] Internet connection found, continuing installation'
131
def searchcard(devices_list, database):
133
Looks if one of the ids in the devices list given as argument matches an entry in the database given as argument.
136
for item in devices_list:
142
def remove_old_drivers():
144
Removes existing wireless drivers.
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])
153
print ' Drivers not loaded, nothing to remove'
155
def blacklist_drivers():
157
Blacklists existing wireless drivers.
160
print '[*] Blacklisting:'
161
baddrivers = yourcard_dic['blacklist']
163
if any(baddrivers in line.split('#')[0] for line in open('/etc/modprobe.d/blacklist')):
164
print ' driver already blacklisted, skipping'
166
print ' writing to /etc/modprobe.d/blacklist'
167
blacklist = open('/etc/modprobe.d/blacklist', 'a')
168
blacklist.write('\n#%s' % (baddrivers, ))
171
def print_driver_license():
173
Checks if the user agrees with the driver's EULA.
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: ')
179
if choice == 'Y' or choice == 'y':
182
elif choice == 'N' or choice == 'n':
186
return driver_license()
188
def create_auto_ndis_folder():
190
Creates a folder in which place the downloaded drivers.
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, ))
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, ))
203
print '[ERROR] can\'t create tmpdir'
204
print ' Either specify an alternative or ensure that /tmp is writable and not full'
207
def find_decompression():
209
Determines the right decompression program to be used with the downloaded driver.
212
decompression = 'manual'
214
if '.exe' in url or '.zip' in url:
215
decompression = 'unzip'
218
decompression = 'tar -vvf'
220
elif '.tar.gz' in url:
221
decompression = 'tar -xvvzf'
223
elif '.tar.bz2' in url:
224
decompression = 'tar -xvvjf'
227
decompression = 'cabextract'
230
decompression = 'unrar'
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, )
243
Downloads the apropiate driver.
246
print '[*] Downloading driver now from "%s"' % (url, )
248
retcode = subprocess.call(['wget', url, '-qO ', opts.tmp_dir + '/' + card_id + '/' + driver, '-o ', opts.tmp_dir + '/' + card_id + '/' + 'wget.log'])
250
retcode = subprocess.call(['wget', url, '-O ', opts.tmp_dir + '/' + card_id + '/' + driver, '-o ', opts.tmp_dir + '/' + card_id + '/' + 'wget.log'])
254
print '[ERROR] Download unsuccessfull, please check your Internet conecction and wget.log in your tmpdir for errors.'
256
print '[DEBUG] wget returned code: %s' % (retcode, )
259
def extract(decompression):
261
Extracts the dowloaded driver.
264
print '[*] Extracting driver'
267
print '[DEBUG] Decompression method: %s' % (decompression, )
269
retcode = subprocess.call([decompression, opts.tmp_dir + '/' + card_id + '/' + driver])
272
print '[WARNING] Decompression may have failed'
275
print '[DEBUG] Decompression method returned code: %s' % (retcode, )
277
choice = raw_input('(C)ontinue, (R)etry, (S)pecify different decompression method or (E)xit: ')
279
if choice == 'C' or choice == 'c':
282
elif choice == 'R' or choice == 'r':
283
return extract(decompression)
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)
291
elif choice == 'E' or choice == 'e':
295
return extract(decompression)
299
Comes into play if the user doesn't have an internet connection or if the driver need to be fetched manually.
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)
307
while not any(driver in line for line in os.listdir('%s/%s/' % (opts.tmp_dir, card_id, ))):
309
dummy = raw_input('When you have succesfully dowloaded the driver and extracted it press <Enter>: ')
312
##Executed when CTRL + C is pressed.
313
print '\n\nCanceled!\n'
316
print '\nDriver file found! Continuing installation.'
320
Installs the driver with NDISwrapper.
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)
330
inf_file, retcode = getoutput('find', opts.tmp_dir + '/' + card_id, '-type', 'f', '-name', driver)
332
create_log_file(inf_file)
335
print '[DEBUG] Driver found at %s' % (inf_file, )
337
#Attempt to install driver
338
output, retcode = getoutput('ndiswrapper', '-i', inf_file)
340
#Attempt to detect errors
341
if 'already' in output:
342
print '\nDriver is already installed'
346
print '[ERROR] Driver installation failed'
348
print '[DEBUG] NDISwrapper returned code: %s' % (retcode, )
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'
359
def create_log_file(driver):
361
Creates a simple log file with some useful info.
364
log = open('autondis-log.txt', 'w')
367
distribution = platform.dist()
368
ndis_version, retcode = getoutput('ndiswrapper', '-v')
370
log.write('OS and date = ')
374
log.write('\nDistribution = ')
375
for item in distribution:
378
log.write('\nNDISwrapper info = ')
380
for item in ndis_version:
383
log.write('\nID = %s \n' % (card_id, ))
384
log.write('URL = %s \n' % (url, ))
385
log.write('DRIVER = %s \n' % (driver, ))
391
Gets the wireless card's id number and revision number.
394
##Gets the id of all the pci devices
395
outtext, retcode = getoutput('lspci', '-n')
397
##Stores the pci ids with the revision number in a list
398
pci = re.findall('.{4}:.{4}\ \(rev .{2}\)',outtext)
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)
405
pcicard = searchcard(pci, data)
406
usbcard = searchcard(usb, data)
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':
413
elif pcicard == 'empty' and usbcard != 'empty':
416
elif pcicard != 'empty' and usbcard != 'empty':
417
choice = raw_input('Setup (w)ificard or setup your (u)sbcard?: ')
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':
424
elif choice == 'U' or choice == 'u':
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()
435
def installation_report():
437
Prompts the user to report the installation if it was succesful.
440
output, retcode = getoutput('ndiswrapper', '-l')
441
print '\n' + 'NDISwrapper output: ' + '\n' + output
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: ')
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 )
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)
455
return installation_report()
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()
464
print '\n[*] Card Supported'
466
print '[*] Card detected as a %s' % (yourcard_dic['name'], )
468
print '[*] Card ciptset detected as a %s' % (yourcard_dic['chipset'], )
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, )
476
print ' Do you want to continue?'
478
dummy = raw_input(' Please hit <Enter> to continue, or use Ctrl+C to cancel: ')
480
print '\n\nCanceled!\n'
484
print '[*] Beginning Setup Procedure:\n'
486
print_driver_license()
487
create_auto_ndis_folder()
489
if decompression != 'manual' and not (opts.manual):
492
extract(decompression)
494
installation_report()
498
installation_report()