Page MenuHomeDevCentral

D3541.id9098.diff
No OneTemporary

D3541.id9098.diff

diff --git a/roles/shellserver/userland-software/base.sls b/roles/shellserver/userland-software/base.sls
--- a/roles/shellserver/userland-software/base.sls
+++ b/roles/shellserver/userland-software/base.sls
@@ -53,8 +53,6 @@
- sockstat
- sysvbanner
- toilet-fonts
- {% else %}
- - woof
{% endif %}
{% if grains['os'] == 'FreeBSD' %}
- bind-tools
@@ -62,6 +60,7 @@
- figlet-fonts
- gsed
- sudo
+ - wurf
{% endif %}
utilities_www:
@@ -71,17 +70,6 @@
- lynx
- w3m
-{% if grains['os_family'] == 'Debian' %}
-{% set network = salt["node.resolve_network"]() %}
-{{ dirs.bin }}/woof:
- file.managed:
- - source: salt://roles/shellserver/userland-software/files/woof.py.jinja
- - mode: 755
- - template: jinja
- - context:
- ip: {{ network["ipv4_address"] }}
-{% endif %}
-
# -------------------------------------------------------------
# More exotic shells
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/roles/shellserver/userland-software/files/woof.py.jinja b/roles/shellserver/userland-software/files/woof.py.jinja
deleted file mode 100755
--- a/roles/shellserver/userland-software/files/woof.py.jinja
+++ /dev/null
@@ -1,556 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-#
-# woof -- an ad-hoc single file webserver
-# Copyright (C) 2004-2009 Simon Budig <simon@budig.de>
-#
-# 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.
-#
-# A copy of the GNU General Public License is available at
-# http://www.fsf.org/licenses/gpl.txt, you can also write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-# Darwin support with the help from Mat Caughron, <mat@phpconsulting.com>
-# Solaris support by Colin Marquardt, <colin.marquardt@zmd.de>
-# FreeBSD support with the help from Andy Gimblett, <A.M.Gimblett@swansea.ac.uk>
-# Cygwin support by Stefan Reichör <stefan@xsteve.at>
-# tarfile usage suggested by Morgan Lefieux <comete@geekandfree.org>
-# File upload support loosely based on code from Stephen English <steve@secomputing.co.uk>
-
-import sys, os, errno, socket, getopt, subprocess, tempfile
-import cgi, urllib.request, urllib.parse, http.server
-import readline
-import configparser
-import shutil, tarfile, zipfile
-import struct
-
-maxdownloads = 1
-cpid = -1
-compressed = 'gz'
-upload = False
-
-
-# Utility function to guess the IP (as a string) where the server can be
-# reached from the outside. Quite nasty problem actually.
-
-def find_ip ():
- # Only for Eglide
- # Up-to-date for 2023-05-30
- return "{{ ip }}"
-
-# our own HTTP server class, fixing up a change in python 2.7
-# since we do our fork() in the request handler
-# the server must not shutdown() the socket.
-
-class ForkingHTTPServer (http.server.HTTPServer):
- def process_request (self, request, client_address):
- self.finish_request (request, client_address)
- self.close_request (request)
-
-
-# Main class implementing an HTTP-Requesthandler, that serves just a single
-# file and redirects all other requests to this file (this passes the actual
-# filename to the client).
-# Currently it is impossible to serve different files with different
-# instances of this class.
-
-class FileServHTTPRequestHandler (http.server.BaseHTTPRequestHandler):
- server_version = "Simons FileServer"
- protocol_version = "HTTP/1.0"
-
- filename = "."
-
- def log_request (self, code='-', size='-'):
- if code == 200:
- http.server.BaseHTTPRequestHandler.log_request (self, code, size)
-
-
- def do_POST (self):
- global maxdownloads, upload
-
- if not upload:
- self.send_error (501, "Unsupported method (POST)")
- return
-
- # taken from
- # http://mail.python.org/pipermail/python-list/2006-September/402441.html
-
- ctype, pdict = cgi.parse_header (self.headers['Content-Type'])
- form = cgi.FieldStorage (fp = self.rfile,
- headers = self.headers,
- environ = {'REQUEST_METHOD' : 'POST'},
- keep_blank_values = 1,
- strict_parsing = 1)
- if "upfile" not in form:
- self.send_error (403, "No upload provided")
- return
-
- upfile = form["upfile"]
-
- if not upfile.file or not upfile.filename:
- self.send_error (403, "No upload provided")
- return
-
- upfilename = upfile.filename
-
- if "\\" in upfilename:
- upfilename = upfilename.split ("\\")[-1]
-
- upfilename = os.path.basename (upfile.filename)
-
- destfile = None
- for suffix in ["", ".1", ".2", ".3", ".4", ".5", ".6", ".7", ".8", ".9"]:
- destfilename = os.path.join (".", upfilename + suffix)
- try:
- destfile = os.open (destfilename, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644)
- break
- except OSError as e:
- if e.errno == errno.EEXIST:
- continue
- raise
-
- if not destfile:
- upfilename += "."
- destfile, destfilename = tempfile.mkstemp (prefix = upfilename, dir = ".")
-
- print ("accepting uploaded file: %s -> %s" % (upfilename, destfilename), file=sys.stderr)
-
- shutil.copyfileobj (upfile.file, os.fdopen (destfile, "wb"))
-
- if upfile.done == -1:
- self.send_error (408, "upload interrupted")
-
- txt = b"""\
- <html>
- <head><title>Woof Upload</title></head>
- <body>
- <h1>Woof Upload complete</title></h1>
- <p>Thanks a lot!</p>
- </body>
- </html>
- """
- self.send_response (200)
- self.send_header ("Content-Type", "text/html")
- self.send_header ("Content-Length", str (len (txt)))
- self.end_headers ()
- self.wfile.write (txt)
-
- maxdownloads -= 1
-
- return
-
-
- def do_GET (self):
- global maxdownloads, cpid, compressed, upload
-
- # Form for uploading a file
- if upload:
- txt = b"""\
- <html>
- <head><title>Woof Upload</title></head>
- <body>
- <h1>Woof Upload</title></h1>
- <form name="upload" method="POST" enctype="multipart/form-data">
- <p><input type="file" name="upfile" /></p>
- <p><input type="submit" value="Upload!" /></p>
- </form>
- </body>
- </html>
- """
- self.send_response (200)
- self.send_header ("Content-Type", "text/html")
- self.send_header ("Content-Length", str (len (txt)))
- self.end_headers ()
- self.wfile.write (txt)
- return
-
- # Redirect any request to the filename of the file to serve.
- # This hands over the filename to the client.
-
- self.path = urllib.parse.quote (urllib.parse.unquote (self.path))
- location = "/" + urllib.parse.quote (os.path.basename (self.filename))
- if os.path.isdir (self.filename):
- if compressed == 'gz':
- location += ".tar.gz"
- elif compressed == 'bz2':
- location += ".tar.bz2"
- elif compressed == 'zip':
- location += ".zip"
- else:
- location += ".tar"
-
- if self.path != location:
- txt = """\
- <html>
- <head><title>302 Found</title></head>
- <body>302 Found <a href="%s">here</a>.</body>
- </html>\n""" % location
- txt = txt.encode ('ascii')
- self.send_response (302)
- self.send_header ("Location", location)
- self.send_header ("Content-Type", "text/html")
- self.send_header ("Content-Length", str (len (txt)))
- self.end_headers ()
- self.wfile.write (txt)
- return
-
- maxdownloads -= 1
-
- # let a separate process handle the actual download, so that
- # multiple downloads can happen simultaneously.
-
- cpid = os.fork ()
-
- if cpid == 0:
- # Child process
- child = None
- type = None
-
- if os.path.isfile (self.filename):
- type = "file"
- elif os.path.isdir (self.filename):
- type = "dir"
-
- if not type:
- print ("can only serve files or directories. Aborting.", file=sys.stderr)
- sys.exit (1)
-
- self.send_response (200)
- self.send_header ("Content-Type", "application/octet-stream")
- self.send_header ("Content-Disposition", "attachment;filename=%s" % urllib.parse.quote (os.path.basename (self.filename + self.archive_ext)))
- if os.path.isfile (self.filename):
- self.send_header ("Content-Length",
- os.path.getsize (self.filename))
- self.end_headers ()
-
- try:
- if type == "file":
- datafile = open (self.filename, "rb")
- shutil.copyfileobj (datafile, self.wfile)
- datafile.close ()
- elif type == "dir":
- if compressed == 'zip':
- zfile = zipfile.ZipFile (self.wfile, 'w', zipfile.ZIP_DEFLATED)
- stripoff = os.path.dirname (self.filename) + os.sep
-
- for root, dirs, files in os.walk (self.filename):
- for f in files:
- filename = os.path.join (root, f)
- if filename[:len (stripoff)] != stripoff:
- raise RuntimeException ("invalid filename assumptions, please report!")
- zfile.write (filename, filename[len (stripoff):])
- zfile.close ()
- else:
- tfile = tarfile.open (mode=('w|' + compressed),
- fileobj=self.wfile)
- tfile.add (self.filename,
- arcname=os.path.basename (self.filename))
- tfile.close ()
-
- except Exception as e:
- print (e)
- print ("Connection broke. Aborting", file=sys.stderr)
-
-
-def serve_files (filename, maxdown = 1, ip_addr = '', port = 8080):
- global maxdownloads
-
- maxdownloads = maxdown
-
- archive_ext = ""
- if filename and os.path.isdir (filename):
- if compressed == 'gz':
- archive_ext = ".tar.gz"
- elif compressed == 'bz2':
- archive_ext = ".tar.bz2"
- elif compressed == 'zip':
- archive_ext = ".zip"
- else:
- archive_ext = ".tar"
-
- # We have to somehow push the filename of the file to serve to the
- # class handling the requests. This is an evil way to do this...
-
- FileServHTTPRequestHandler.filename = filename
- FileServHTTPRequestHandler.archive_ext = archive_ext
-
- try:
- httpd = ForkingHTTPServer ((ip_addr, port), FileServHTTPRequestHandler)
- except socket.error:
- print ("cannot bind to IP address '%s' port %d" % (ip_addr, port), file=sys.stderr)
- sys.exit (1)
-
- if not ip_addr:
- ip_addr = find_ip ()
- if ip_addr:
- if filename:
- location = (f"http://{ip_addr}:{httpd.server_port}/" +
- urllib.parse.quote (os.path.basename (filename + archive_ext)))
- else:
- location = "http://%s:%s/" % (ip_addr, httpd.server_port)
-
- print ("Now serving on %s" % location)
-
- while cpid != 0 and maxdownloads > 0:
- httpd.handle_request ()
-
-
-
-def usage (defport, defmaxdown, errmsg = None):
- name = os.path.basename (sys.argv[0])
- print ("""
- Usage: %s [-i <ip_addr>] [-p <port>] [-c <count>] <file>
- %s [-i <ip_addr>] [-p <port>] [-c <count>] [-z|-j|-Z|-u] <dir>
- %s [-i <ip_addr>] [-p <port>] [-c <count>] -s
- %s [-i <ip_addr>] [-p <port>] [-c <count>] -U
-
- %s <url>
-
- Serves a single file <count> times via http on port <port> on IP
- address <ip_addr>.
- When a directory is specified, an tar archive gets served. By default
- it is gzip compressed. You can specify -z for gzip compression,
- -j for bzip2 compression, -Z for ZIP compression or -u for no compression.
- You can configure your default compression method in the configuration
- file described below.
-
- When -s is specified instead of a filename, %s distributes itself.
-
- When -U is specified, woof provides an upload form, allowing file uploads.
-
- defaults: count = %d, port = %d
-
- If started with an url as an argument, woof acts as a client,
- downloading the file and saving it in the current directory.
-
- You can specify different defaults in two locations: /etc/woofrc
- and ~/.woofrc can be INI-style config files containing the default
- port and the default count. The file in the home directory takes
- precedence. The compression methods are "off", "gz", "bz2" or "zip".
-
- Sample file:
-
- [main]
- port = 8008
- count = 2
- ip = 127.0.0.1
- compressed = gz
- """ % (name, name, name, name, name, name, defmaxdown, defport), file=sys.stderr)
-
- if errmsg:
- print (errmsg, file=sys.stderr)
- print (file=sys.stderr)
- sys.exit (1)
-
-
-
-def woof_client (url):
- urlparts = urllib.parse.urlparse (url, "http")
- if urlparts[0] not in [ "http", "https" ] or urlparts[1] == '':
- return None
-
- fname = None
-
- f = urllib.request.urlopen (url)
-
- f_meta = f.info ()
- disp = f_meta["Content-Disposition"]
-
- if disp:
- disp = disp.split (";")
-
- if disp and disp[0].lower () == 'attachment':
- fname = [x[9:] for x in disp[1:] if x[:9].lower () == "filename="]
- if len (fname):
- fname = fname[0]
- else:
- fname = None
-
- if fname == None:
- url = f.geturl ()
- urlparts = urllib.parse.urlparse (url)
- fname = urlparts[2]
-
- if not fname:
- fname = "woof-out.bin"
-
- if fname:
- fname = urllib.parse.unquote (fname)
- fname = os.path.basename (fname)
-
- readline.set_startup_hook (lambda: readline.insert_text (fname))
- fname = input ("Enter target filename: ")
- readline.set_startup_hook (None)
-
- override = False
-
- destfile = None
- destfilename = os.path.join (".", fname)
- try:
- destfile = os.open (destfilename,
- os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644)
- except OSError as e:
- if e.errno == errno.EEXIST:
- override = input ("File exists. Overwrite (y/n)? ")
- override = override.lower () in [ "y", "yes" ]
- else:
- raise
-
- if destfile == None:
- if override == True:
- destfile = os.open (destfilename, os.O_WRONLY | os.O_CREAT, 0o644)
- else:
- for suffix in [".1", ".2", ".3", ".4", ".5", ".6", ".7", ".8", ".9"]:
- destfilename = os.path.join (".", fname + suffix)
- try:
- destfile = os.open (destfilename,
- os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644)
- break
- except OSError as e:
- if e.errno == errno.EEXIST:
- continue
- raise
-
- if not destfile:
- destfile, destfilename = tempfile.mkstemp (prefix = fname + ".",
- dir = ".")
- print ("alternate filename is:", destfilename)
-
- print ("downloading file: %s -> %s" % (fname, destfilename))
-
- shutil.copyfileobj (f, os.fdopen (destfile, "wb"))
-
- return 1;
-
-
-
-def main ():
- global cpid, upload, compressed
-
- maxdown = 1
- port = 8080
- ip_addr = ''
-
- config = configparser.ConfigParser ()
- config.read (['/etc/woofrc', os.path.expanduser ('~/.woofrc')])
-
- if config.has_option ('main', 'port'):
- port = config.getint ('main', 'port')
-
- if config.has_option ('main', 'count'):
- maxdown = config.getint ('main', 'count')
-
- if config.has_option ('main', 'ip'):
- ip_addr = config.get ('main', 'ip')
-
- if config.has_option ('main', 'compressed'):
- formats = { 'gz' : 'gz',
- 'true' : 'gz',
- 'bz' : 'bz2',
- 'bz2' : 'bz2',
- 'zip' : 'zip',
- 'off' : '',
- 'false' : '' }
- compressed = config.get ('main', 'compressed')
- compressed = formats.get (compressed, 'gz')
-
- defaultport = port
- defaultmaxdown = maxdown
-
- try:
- options, filenames = getopt.gnu_getopt (sys.argv[1:], "hUszjZui:c:p:")
- except getopt.GetoptError as desc:
- usage (defaultport, defaultmaxdown, desc)
-
- for option, val in options:
- if option == '-c':
- try:
- maxdown = int (val)
- if maxdown <= 0:
- raise ValueError
- except ValueError:
- usage (defaultport, defaultmaxdown,
- "invalid download count: %r. "
- "Please specify an integer >= 0." % val)
-
- elif option == '-i':
- ip_addr = val
-
- elif option == '-p':
- try:
- port = int (val)
- except ValueError:
- usage (defaultport, defaultmaxdown,
- "invalid port number: %r. Please specify an integer" % val)
-
- elif option == '-s':
- filenames.append (__file__)
-
- elif option == '-h':
- usage (defaultport, defaultmaxdown)
-
- elif option == '-U':
- upload = True
-
- elif option == '-z':
- compressed = 'gz'
- elif option == '-j':
- compressed = 'bz2'
- elif option == '-Z':
- compressed = 'zip'
- elif option == '-u':
- compressed = ''
-
- else:
- usage (defaultport, defaultmaxdown, "Unknown option: %r" % option)
-
- if upload:
- if len (filenames) > 0:
- usage (defaultport, defaultmaxdown,
- "Conflicting usage: simultaneous up- and download not supported.")
- filename = None
-
- else:
- if len (filenames) == 1:
- if woof_client (filenames[0]) != None:
- sys.exit (0)
-
- filename = os.path.abspath (filenames[0])
- else:
- usage (defaultport, defaultmaxdown,
- "Can only serve single files/directories.")
-
- if not os.path.exists (filename):
- usage (defaultport, defaultmaxdown,
- "%s: No such file or directory" % filenames[0])
-
- if not (os.path.isfile (filename) or os.path.isdir (filename)):
- usage (defaultport, defaultmaxdown,
- "%s: Neither file nor directory" % filenames[0])
-
- serve_files (filename, maxdown, ip_addr, port)
-
- # wait for child processes to terminate
- if cpid != 0:
- try:
- while 1:
- os.wait ()
- except OSError:
- pass
-
-
-
-if __name__=='__main__':
- try:
- main ()
- except KeyboardInterrupt:
- print ()

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 23, 07:28 (17 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2256823
Default Alt Text
D3541.id9098.diff (19 KB)

Event Timeline