pstd - command line pastebin
Perl Shell Other
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


pstd (pasted) - command line pastebin (version 0.0.2)

Quickstart for running a pstd paste site
(To be documented in detail later, but as a quick example, this is how is run (referring to it as henceforth)

# Optional: authbind setup (assuming it is installed)
$ sudo touch /etc/authbind/byport/80
$ sudo chown $(whoami) /etc/authbind/byport/80
$ sudo chmod 100 /etc/authbind/byport/80
# (authbind's policy is that a user may bind to a the port if they have
# execute permissions on the file /etc/authbind/byport/<theport>)

# Site setup:
$ git clone
$ cd pstd
$ mkdir pastes
# Then depending on whether or not authbind was used, one of the following:
$ ./ -l -H  #without authbind
$ authbind --deep ./ -l -H  #with authbind

If that worked, (or should contain
further information on how to submit pastes

I didn't want to run a httpd in front of this because what we really need from
HTTP is but a tiny subset of the protocol; hence a httpd (or even a HTTP lib)
would add considerable attack surface.  Therefore generates and
parses the few HTTP messages we support itself.  For a web browser looking at
pastes, this shouldn't matter at all, but for submitting pastes (which can't,
by design, be done in a web browser), there's one major consequence:
The only way to submit a paste is to submit it as a POST request *without any
non-identity "Transfer-Encoding" (like, chunked, or multipart w/ boundary)*.
This implies that the POST request has a "Content-Length" header.
This is the reason for why curl(1) cannot be used to submit pastes like on
sprunge; wget(1) (--post-file) has to be used instead.  However, wget(1) comes
with its own problem of being unable to POST standard input (for it needs to
know the data length in advance).
To cope with this problems, a POSIX shell script "" has been written to
facilitate more convenient pasting (including standard input; it's essentially
a wrapper around wget(1) using a temporary file).  This script is automatically
made available as paste "0" and referred to in the (web-visible) manual page.

This and that
- The paste IDs we hand out start as 2-letter permutations of [A-Za-z0-0]. Once
  that namespace is (more or less) full (as determined by 10 failed attempts to
  generate an unused ID of that length), the ID length will be raised to three,
  and so forth, up to 32.  This provides plenty or namespace to make sure that
  before we run out of IDs, we'll run out of hard disk space (or sunlight...).

- There's a upper limit on how large a single paste may be, defaults to 256 KB

- Requesting the site root will produce a man page with further information on
  how to submit pastes

- To avoid running as root but still be able to bind to a low-numbered port,
  a NAT setup can be used, or on Linux, authbind(1) has been shown to work.

- Rate limiting is controlled by the -r and -R command line options.
  The argument to -R specifies the size of a (sliding) time window to be
  considered (in seconds), while -r gives the maximum number of attempts to
  paste that may happen (per IP) in that time window. Attempting to paste
  while already rate-limited may extend the period the offender has to wait.
  Note that the amount of memory required per pasting IP goes up linearly
  with the argument to -r (but not -R), so if memory is a concern, better
  turn down -R rather than turning up -r to relax the rate limiting.

- Using the -C and -D command line switches, programs for compression and
  decompression of pastes can be specified.  The arguments to -C and -D should
  be strings representing the command-lines (incl. switches, if any) to
  invoke a compressor and a decompressor, respectively, in a way that they
  act as filter (i.e. (de)compress stdin to stdout).
  For example: -C gzip -D gzcat
  By default, no compression is done (technically, it's -C cat -D cat).
  Since these programs are shell-ed out, be careful what you specify.
  The script does not care if it's 'rm -rf ~' or a fork bomb.

- If a link to a paste is suffixed with ?<lang>, then syntax hilighting for
  language <lang> is generated, so long as the site has a program that does
  that.  This is controlled by the -y command line switch, the argument of
  which must be a comma separated string of <lang>:<commandline> tokens,
  where <commandline> represents the way to invoke an external filter that,
  when presented with a source file on stdin, produces formatted HTML on stdout.
  E.g. -y 'c:chilight -f html_color,java:javaprettifier -foobar'

Reasons for writing this
On 2015-05-15, was unavailable for about 24 hours, and at that time
was used as the primary (and only) paste backend for a number of scripts (most
notably  I considered running the sprunge code
( but decided against it because I'm not so fond
of python and/or depending on google's cloud storage (or any cloud storage for
that matter).  Regular web-based pastebins also didn't fit my use-case for they
make it unnecessarily difficult to submit data without a web browser.

- There is no mechanism for limited-lifespan pastes yet

- In-memory caching of the most frequenly requested pastes?

Author + License
(C) 2015, Timo Buhrmester

pstd is licensed under a 2-clause BSD license, without any warranty, but with
best wishes and in the hope it will be useful (also see the LICENSE file).