You are not logged in.
OK, thanks.
Offline
btw about that bug I found in powerpill about it downloading the packages but not running pacman I think it might be because I pressed a button while it was running and it hiden pacman's output.
Offline
Xyne, did you also think about a server, which provides a site to upload files? I'd love to have sth like that, so others can send me files. I know there's always a security risk, but what about you combine it with quixand?
Offline
Another similar project is woof.
Offline
@Army
That might be relatively easy to do with a multipart form. Combining it with quixand would be left to the user along with all other security concerns (plaintext file transfers, etc). I'll give this some thought when I have the time.
@N3ON
I wasn't aware of woof either, but from the description it seems "limited" to a single file.
My Arch Linux Stuff • Forum Etiquette • Community Ethos - Arch is not for everyone
Offline
...
@N3ON
I wasn't aware of woof either, but from the description it seems "limited" to a single file.
Woof is indeed "limited" to a single file, if you like to transfer more files woof combines files inside directories into a tar/zip/rar/... on the fly.
In my opinion it would be really cool if quickserve could get a download-link behind the dir-listing to call woof.
hmmm, this sounds like a feature request...is that allowed? ...anyways, thanks for this fine app.
Offline
@Army
That might be relatively easy to do with a multipart form. Combining it with quixand would be left to the user along with all other security concerns (plaintext file transfers, etc). I'll give this some thought when I have the time.
Cool, thanks :-)
Offline
I am using this program from past 15days and Its very useful.Good work from Developer/coder
however, I have just one request
Please make directory listing more readable currently its very difficult to view files and directories.
Hoping you would make it more better:D
Last edited by cool (2010-01-09 17:31:52)
Offline
Hey, I changed some things and added some small things.
Screenshot:
Code:
#!/usr/bin/env python
# Copyright (C) 2009 Xyne
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# METADATA
# Version: 2.3
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from hashlib import md5
from mimetypes import guess_type
import os.path
from optparse import OptionParser
from urllib import quote, unquote
class QuickServeHandler(BaseHTTPRequestHandler):
def allow(self):
username = options.username
password = options.password
if username and password:
if 'Authorization' in self.headers and self.headers['Authorization'][:7] == 'Digest ':
#client_username = None
client_response = None
#realm = None
nonce = None
for field in self.headers['Authorization'][7:].split(', '):
#if field[:10] == 'username="':
# client_username = field[10:-1].replace('\"', '"')
#el
if field[:10] == 'response="':
client_response = field[10:-1]
#elif field[:7] == 'realm="':
# realm = field[7:-1]
elif field[:7] == 'nonce="':
nonce = field[7:-1]
if client_response != None and nonce != None:
m = md5()
m.update(username + ':' + self.address_string() + ':' + password)
ha1 = m.hexdigest()
m = md5()
m.update('GET:' + self.path)
ha2 = m.hexdigest()
m = md5()
m.update(ha1 + ':' + nonce + ':' + ha2)
response = m.hexdigest()
if response == client_response:
return True
return False
elif not username and not password:
return True
return False
def do_GET(self):
if not self.allow():
self.send_response(401)
self.send_header('WWW-Authenticate', 'Digest realm="' + self.address_string() + '"')
self.send_header('Connection', 'close')
self.end_headers()
return
global paths
if self.path == '/':
self.send_response(200)
self.send_header('Content-type', 'text/html; charset=UTF-8')
self.end_headers()
html = generate_html(None, sorted(paths.keys()))
self.wfile.write(safe_encode_utf8(html))
return
else:
splitpath = self.path[1:].split(os.sep,1)
if splitpath[0] in paths:
if splitpath[0] == self.path[1:]:
fpath = paths[splitpath[0]]
elif len(splitpath) == 2:
fpath = os.path.join(paths[splitpath[0]], splitpath[1])
else:
fpath = None
if fpath:
fpath = unquote(fpath)
if os.path.isfile(fpath):
self.transfer_file(fpath)
return
elif os.path.isdir(fpath):
dirs, files = get_dirs_and_files(fpath)
html = generate_html(self.path, map(lambda x: os.path.join(self.path, x), dirs + files), True)
self.send_response(200)
self.send_header('Content-type', 'text/html; charset=UTF-8')
self.end_headers()
self.wfile.write( safe_encode_utf8(html) )
return
self.send_response(404)
self.send_header('Connection', 'close')
self.end_headers()
def do_POST(self):
self.send_response(403)
self.send_header('Connection', 'close')
self.end_headers()
def transfer_file(self, fpath):
self.send_response(200)
size = os.path.getsize(fpath)
range_start = 0
range_end = size - 1
mimetype = guess_type(fpath)
if not mimetype:
mimetype = 'application/octet-stream'
self.send_header('Accept-Ranges', 'bytes')
self.send_header('Content-Type', mimetype)
if 'range' in self.headers:
s, e = self.headers['range'][6:].split('-', 1)
if len(s) > 0:
range_start = int(s)
if len(e) > 0:
range_end = int(e)
self.send_header('Content-Range', 'bytes ' + str(range_start) + '-' + str(range_end) + '/' + str(size))
self.send_header('Content-Length', range_end - range_start + 1)
self.end_headers()
f = open(fpath, 'rb')
f.seek(range_start, 0)
step = 4096
total = 0
while step > 0:
if range_start + step > range_end + 1:
step = range_end - range_start + 1
try:
self.wfile.write(f.read(step))
except:
break
total += step
range_start += step
f.close()
def safe_encode_utf8(text):
try:
return text.encode('utf-8')
except UnicodeDecodeError:
return text
def get_dirs_and_files(path):
if os.path.isdir(path):
paths = os.listdir(path)
return sorted(filter(lambda x: os.path.isdir(os.path.join(path,x)), paths)), \
sorted(filter(lambda x: os.path.isfile(os.path.join(path,x)), paths))
elif os.path.isfile(path):
return [], [os.path.basename(path)]
else:
return [], []
def generate_html(title, urls, backlink=False):
if title is None:
title = '/'
else:
title = title
if backlink and title != '/':
backlink = ' <a href="/%s">[Back]</a>' % \
'/'.join(title.split('/')[1:-1])
else:
backlink = ''
filelist_html = ''
for url in urls:
#url = quote(url)
filelist_html += ''' <li><a href="%s">%s</a></li>\n''' % \
(url, os.path.basename(url))
if len(urls) == 0:
filelist_html = '<li>No files found.</li>'
return '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>%(title)s - Quickserve</title>
<style type="text/css">
html, body { background-color: #fff;padding: 0;margin: 0 }
body { font-size: 85%%;line-height: 1.5em;color: #222;
font-family: "Lucida Grande", "Lucida Sans Unicode",
"Lucida Sans", Verdana, Arial, sans-serif }
#wrapper { margin: 0 auto;width: 90%% }
h1 { font-weight: normal;color: #333;margin-bottom: 0.5em;
font-size: 3em;line-height: 1em }
ul { margin:0 0.5em 1.5em;padding: 0 0 2em 2.5em;
list-style-type: square }
h1 a { font-size: 0.5em;text-decoration: none }
</style>
</head>
<body>
<div id="wrapper">
<h1>%(title)s%(backlink)s</h1>
<ul>
%(filelist)s </ul>
</div>
</body>
</html>
''' % {'title': unquote(title), 'filelist': filelist_html, 'backlink': backlink}
def main(address='localhost', port=8080):
try:
server = HTTPServer((address, port), QuickServeHandler)
print 'Started httpserver on %s:%d...' % (address, port)
server.serve_forever()
except KeyboardInterrupt:
print '^C received, shutting down server'
server.socket.close()
if __name__ == '__main__':
myname = 'quickserve'
parser = OptionParser(description='%s - a simple HTTP server for quickly'
' sharing files' % myname,
usage='%s [options] [paths]' % myname)
parser.add_option('-b', '--bind', dest='address', default='',
action='store',
help='Bind the server to this address. By default the'
'server will listen on all interfaces.')
parser.add_option('-p', '--port', dest='port', default=8080, type='int',
action='store',
help='Set the server port (default: 8080)')
parser.add_option('-u', '--username', dest='username', action='store',
help='Set authentication username.')
parser.add_option('--password', dest='password', action='store',
help='Set authentication password.')
(options, args) = parser.parse_args()
global paths, username, password
username = options.username
password = options.password
paths = {}
for a in args:
a = os.path.abspath(a)
paths[os.path.basename(a)] = a
main(options.address, options.port)
Offline
I've just finished adding sizes and mtimes, along with the link to the parent directory. I'll have a look at what FSX has added and merge anything that I find useful.
*edit*
I've merged some of FSX's changes into Quickserve (inclusion of DOCTYPE string, some CSS styles, inclusion of header, name of parent directory link).
Thanks, FSX.
Last edited by Xyne (2010-01-10 01:09:20)
My Arch Linux Stuff • Forum Etiquette • Community Ethos - Arch is not for everyone
Offline
It doesn't seem to play nice with folders that have spaces in their names. But besides that, it's great.
I'm using the latest revision and haven't tried any of the previous ones.
----------------------------------------
----------------------------------------
Exception happened during processing of request from ('192.168.1.100', 53860)
Traceback (most recent call last):
File "/usr/lib/python2.6/SocketServer.py", line 281, in _handle_request_noblock
self.process_request(request, client_address)
File "/usr/lib/python2.6/SocketServer.py", line 307, in process_request
self.finish_request(request, client_address)
File "/usr/lib/python2.6/SocketServer.py", line 320, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python2.6/SocketServer.py", line 615, in __init__
self.handle()
File "/usr/lib/python2.6/BaseHTTPServer.py", line 329, in handle
self.handle_one_request()
File "/usr/lib/python2.6/BaseHTTPServer.py", line 323, in handle_one_request
method()
File "/usr/bin/quickserve", line 104, in do_GET
html = get_html(self.path, dirs + files)
File "/usr/bin/quickserve", line 198, in get_html
stat = os.stat(upath)
OSError: [Errno 2] No such file or directory: '//home/timothy/Misc/Music/Albums/Carbon%20Based%20Lifeforms/Hydroponic Garden'
Offline
@Pnevma
Too bad that you didn't try the previous version... the space bug was introduced in the last update. I missed an "unquote" when changing around one of the functions.
Please try the latest version and confirm that it works.
Last edited by Xyne (2010-01-10 03:44:07)
My Arch Linux Stuff • Forum Etiquette • Community Ethos - Arch is not for everyone
Offline
Yeah, that's what I figured
I just tried the new version and can confirm that it's fixed. Thanks!
Offline
Thanks for reporting the bug and confirming the fix.
My Arch Linux Stuff • Forum Etiquette • Community Ethos - Arch is not for everyone
Offline
@Xyne thank you for your great work. I used to use abyss to serve data file, but your tool is perfect
====* -- Joke
O
\|/ --- Me
/ \ Whooooosh
Offline
I used the already mentioned - woof - to simple share stuff in my LAN. But now quickserve surpassed it due to folder sharing and authorization. Thanks a lot Xyne!
Offline
I've been using ArchLinux for a while now and it's about time I get into the whole community of it all.
Xyne, I don't know how this sounds (I've kinda been awake too long), but I had this nagging feeling that something was missing from your script. So in the spirit of late morning coffee binges, I toyed with it and fixed two bugs that I noticed; (allow() was using options instead of the global variables; and that nothing was shared there are no command line options).
These updates add two new options that I think would be appricated;
-r which generates a random username and password, allowing for increased psuedo-security. And
-d displays the URL of the quickserv server to the screen. This url includes the authentication data, and I have found it useful when sharing the URL over IM (especially when combining it with -r).
Quick preview of the new features look like thus;
undisbeliever@deadlocked ~/src $ ./quickserve -rd
Username: NoxXGUnD
Password: WzDewkZy
http://NoxXGUnD:WzDewkZy@deadlocked:8080/
started httpserver on :8080...
Take the changes, or leave your code as-is. I was mainly doing this to gain experience in going through and working with someone elses code (something they don't really teach you at univeristy, along with proper coding semantics).
#!/usr/bin/env python
# Copyright (C) 2009 Xyne
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# METADATA
# Version: 2.4.2
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from hashlib import md5
from mimetypes import guess_type
import os.path
from optparse import OptionParser
from time import gmtime,strftime
from urllib import unquote
from socket import gethostname
import string
import random
class MyHandler(BaseHTTPRequestHandler):
def allow(self):
global username, password
if username and password:
if 'Authorization' in self.headers and self.headers['Authorization'][:7] == 'Digest ':
#client_username = None
client_response = None
#realm = None
nonce = None
for field in self.headers['Authorization'][7:].split(', '):
#if field[:10] == 'username="':
# client_username = field[10:-1].replace('\"', '"')
#el
if field[:10] == 'response="':
client_response = field[10:-1]
#elif field[:7] == 'realm="':
# realm = field[7:-1]
elif field[:7] == 'nonce="':
nonce = field[7:-1]
if client_response != None and nonce != None:
m = md5()
m.update(username + ':' + self.address_string() + ':' + password)
ha1 = m.hexdigest()
m = md5()
m.update('GET:' + self.path)
ha2 = m.hexdigest()
m = md5()
m.update(ha1 + ':' + nonce + ':' + ha2)
response = m.hexdigest()
if response == client_response:
return True
return False
elif not username and not password:
return True
else:
return False
def do_GET(self):
if not self.allow():
self.send_response(401)
self.send_header('WWW-Authenticate', 'Digest realm="' + self.address_string() + '"')
self.send_header('Connection', 'close')
self.end_headers()
return
global paths
if self.path == '/':
self.send_response(200)
self.send_header('Content-type', 'text/html; charset=UTF-8')
self.end_headers()
html = get_html(self.path, sorted(paths.keys()))
self.wfile.write( safe_encode_utf8(html) )
return
else:
splitpath = self.path[1:].split(os.sep,1)
if splitpath[0] in paths:
if splitpath[0] == self.path[1:]:
fpath = paths[splitpath[0]]
elif len(splitpath) == 2:
fpath = os.path.join(paths[splitpath[0]], splitpath[1])
else:
fpath = None
if fpath:
fpath = unquote(fpath)
if os.path.isfile(fpath):
self.transfer_file(fpath)
return
elif os.path.isdir(fpath):
dirs, files = get_dirs_and_files(fpath)
html = get_html(self.path, dirs + files)
self.send_response(200)
self.send_header('Content-type', 'text/html; charset=UTF-8')
self.end_headers()
self.wfile.write( safe_encode_utf8(html) )
return
self.send_response(404)
self.send_header('Connection', 'close')
self.end_headers()
def do_POST(self):
self.send_response(403)
self.send_header('Connection', 'close')
self.end_headers()
def transfer_file(self,fpath):
self.send_response(200)
size = os.path.getsize(fpath)
range_start = 0
range_end = size - 1
mimetype = guess_type(fpath)
if not mimetype:
mimetype = 'application/octet-stream'
self.send_header('Accept-Ranges', 'bytes')
self.send_header('Content-Type', mimetype)
if 'range' in self.headers:
s, e = self.headers['range'][6:].split('-', 1)
if len(s) > 0:
range_start = int(s)
if len(e) > 0:
range_end = int(e)
self.send_header('Content-Range', 'bytes ' + str(range_start) + '-' + str(range_end) + '/' + str(size))
self.send_header('Content-Length', range_end - range_start + 1)
self.end_headers()
f = open(fpath, 'rb')
f.seek(range_start, 0)
step = 4096
total = 0
while step > 0:
if range_start + step > range_end + 1:
step = range_end - range_start + 1
try:
self.wfile.write(f.read(step))
except:
break
total += step
range_start += step
f.close()
def safe_encode_utf8(text):
try:
return text.encode('utf-8')
except UnicodeDecodeError:
return text
def get_dirs_and_files(path):
if os.path.isdir(path):
paths = os.listdir(path)
return sorted(filter(lambda x: os.path.isdir(os.path.join(path,x)), paths)), sorted(filter(lambda x: os.path.isfile(os.path.join(path,x)), paths))
elif os.path.isfile(path):
return [], [os.path.basename(path)]
else:
return [], []
def get_html(path,contents):
global paths
path = unquote(path)
i = path.find('/',1)
if i > 0:
root = path[1:i]
else:
root = path[1:]
if root != '':
backlink = '<a href="%s">[Back]</a>' % ('/' + path[1:].rpartition('/')[0])
else:
backlink = ''
filelist_html = "<table>\n<tr><th>File</th><th>Size</th><th>Last Modified (GMT)</th></tr>\n"
for c in contents:
if root != '':
upath = path.replace(root, paths[root]) + '/' + c
href = path + '/' + c
else:
upath = paths[c]
href = '/' + c
stat = os.stat(upath)
gm_time = gmtime(stat.st_mtime)
str_time = strftime("%Y-%m-%d %H:%M:%S", gm_time)
if os.path.isdir(upath):
c += '/'
size = ''
else:
size = format_size(stat.st_size)
filelist_html += '<tr><td><a href="' + href + '">' + c + '</a></td><td class="alignr">' + size + '</td><td>' + str_time + "</td></tr>\n"
filelist_html += "</table>\n"
html = '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>%(title)s - Quickserve</title>
<style type="text/css">
html, body { background-color: #fff;padding: 0;margin: 0 }
body { font-family: "Lucida Grande", "Lucida Sans Unicode",
"Lucida Sans", Verdana, Arial, sans-serif }
#wrapper { margin: 0 auto;width: 90%% }
h1 { font-weight: normal; color: #333; margin-bottom: 0.5em;
font-size: 2.5em; line-height: 1em }
h1 a { font-size: 0.5em; text-decoration: none; margin-left: 1em; }
table { font-family: monospace; border-spacing:10px 4px; margin-bottom: 5em }
th { text-align: left }
.alignr { text-align: right }
</style>
</head>
<div id="wrapper">
<h1>%(title)s%(backlink)s</h1>
%(filelist)s
</div>
</body>
''' % {'title': unquote(path), 'filelist': filelist_html, 'backlink': backlink}
return html
def format_size(size):
s = ' B'
if size > 1000:
size /= 1000.0
s = 'kB'
if size > 1000:
size /= 1000.0
s = 'MB'
if size > 1000:
size /= 1000.0
s = 'GB'
if size > 1000:
size /= 1000.0
s = 'TB'
return "%.02f %s" % (size,s)
def create_random_password(chars=string.ascii_letters, len=8):
global username, password
username = "".join(random.choice(chars) for x in range(len))
password = "".join(random.choice(chars) for x in range(len))
print 'Username:', username
print 'Password:', password
def server_url(address=None, port=8080):
global username, password
if address is None or address is '':
address = gethostname()
if not username and not password:
return 'http://%s:%d/' % (address, port)
else:
return 'http://%s:%s@%s:%d/' % (username, password, address, port)
def main(address='localhost', port=8080):
try:
server = HTTPServer((address, port), MyHandler)
print 'started httpserver on %s:%d...' % (address, port)
server.serve_forever()
except KeyboardInterrupt:
print '^C received, shutting down server'
server.socket.close()
if __name__ == '__main__':
myname = 'quickserve'
parser = OptionParser(description=myname + ' - a simple HTTP server for quickly sharing files', usage=myname + ' [options] [paths]')
parser.add_option("-b", "--bind", dest="address", default='', action="store",
help='Bind the server to this address. By default the server will listen on all interfaces.')
parser.add_option("-p", "--port", dest="port", default=8080, type="int", action="store",
help='Set the server port (default: 8080)')
parser.add_option("-u", "--username", dest="username", action="store",
help='Set authentication username.')
parser.add_option("--password", dest="password", action="store",
help='Set authentication password.')
parser.add_option("-r", "--random", dest="random_password", default=False, action="store_true",
help='Use a randomly generated authentication username and password. Overrides --username and --password.')
parser.add_option("-d", "--display-url", dest="display_url", default=False, action="store_true",
help='Displays the URL of the web server (including authentication). Useful for when commuicating over IM.')
(options, args) = parser.parse_args()
global paths, username, password
username = options.username
password = options.password
if options.random_password :
create_random_password()
if options.display_url :
print server_url(options.address, options.port)
paths = {}
for a in args:
a = os.path.abspath(a)
paths[os.path.basename(a)] = a
if len(paths) == 0:
a = os.getcwd()
paths[os.path.basename(a)] = a
main(options.address, options.port)
Army; as for the file uploading idea, there is a python script that could be modified to do this (http://fragments.turtlemeat.com/pythonwebserver.php). I've had some experience using python to create a HTTP_POST dummy server. I could probably add this option to quickserv if Xyne doesn't mind.
EDIT: I forgot to give you my thanks for creating this script. I've used it quite a few times in the last weekend and it working wondeerfully for my needs.
Last edited by UnDisbeliever (2010-01-13 22:48:37)
Offline
To add to the chorus of thanks: I just discovered quickserve and it's wonderful. Thanks!!!
Offline
I'd like to have it share the current folder when quickserve is ran without path parameters.
Offline
I'd like to have it share the current folder when quickserve is ran without path parameters.
So you want to be able to do
quickserve
because
quickserve .
is too much to type?
My Arch Linux Stuff • Forum Etiquette • Community Ethos - Arch is not for everyone
Offline
Ape wrote:I'd like to have it share the current folder when quickserve is ran without path parameters.
So you want to be able to do
quickserve
because
quickserve .
is too much to type?
You are absolutely right there.
Offline
I'm reluctant to do that because it poses a slight security risk as it makes it easier to accidentally share a directory, which is potentially dangerous. It also adds a few lines to the code, all just to save 2 characters of typing which could easily be aliased in your .bashrc (alias quickserve="/usr/bin/quickserve .").
Sorry, but I don't think I'll implement that.
My Arch Linux Stuff • Forum Etiquette • Community Ethos - Arch is not for everyone
Offline
Sorry, but I don't think I'll implement that.
Well I understand your point, but this was the command I tried first. I somehow thought that it would serve the current folder. Currently it outputs this:
$ quickserve
started httpserver on :8080...
Maybe you should make it more informative and say something like this:
$ quickserve
usage: quickserve [path for sharing]
Also when I start the command with folder share and add or remove the files within, quickserve doesn't see the changes.
Offline
Ok, it now prints out the help message and exits when run without any paths. It also lists what it's serving when started.
My Arch Linux Stuff • Forum Etiquette • Community Ethos - Arch is not for everyone
Offline
toad@deskarch 981\12 ~ > quickserve
Traceback (most recent call last):
File "/usr/bin/quickserve", line 293, in <module>
main(options.address, options.port)
File "/usr/bin/quickserve", line 263, in main
server = HTTPServer((address, port), MyHandler)
File "/usr/lib/python2.6/SocketServer.py", line 400, in __init__
self.server_bind()
File "/usr/lib/python2.6/BaseHTTPServer.py", line 108, in server_bind
SocketServer.TCPServer.server_bind(self)
File "/usr/lib/python2.6/SocketServer.py", line 411, in server_bind
self.socket.bind(self.server_address)
File "<string>", line 1, in bind
socket.error: [Errno 98] Address already in use
??
I then tried to upgrade:
-> Downloading quickserve-2.5.tar.gz...
--2010-01-16 12:20:37-- http://xyne.archlinux.ca/src/quickserve-2.5.tar.gz
Resolving xyne.archlinux.ca... 69.89.25.172
Connecting to xyne.archlinux.ca|69.89.25.172|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10102 (9.9K) [application/x-gzip]
Saving to: `quickserve-2.5.tar.gz.part'
100%[=========================================================================================================================>] 10,102 25.1K/s in 0.4s
2010-01-16 12:20:38 (25.1 KB/s) - `quickserve-2.5.tar.gz.part' saved [10102/10102]
==> Validating source files with md5sums...
quickserve-2.5.tar.gz ... FAILED
==> ERROR: One or more files did not pass the validity check!
Error: Makepkg was unable to build quickserve package.
Error: unable to update quickserve
Following packages have not been installed:
quickserve
toad@deskarch 982\14 ~ >
Is it just me or something else?
never trust a toad...
::Grateful ArchDonor::
::Grateful Wikipedia Donor::
Offline