From ea3052fb3a55167c92db81199e780f72ac0f5948 Mon Sep 17 00:00:00 2001
From: eleksir
Date: Fri, 17 Mar 2017 19:56:33 +0300
Subject: [PATCH] Initial commit
---
README.md | 118 +++++++++++++++++
index.php | 374 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 492 insertions(+)
create mode 100644 README.md
create mode 100644 index.php
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..356a739
--- /dev/null
+++ b/README.md
@@ -0,0 +1,118 @@
+## Paste. ##
+
+This is pastebin replacement. It does not use ads, it is opensource it is relatively small.
+And it has minimal pastebin API stub, at least pastebinit can paste to it with minimal config changes.
+Besides pastebinit there are 2 cli clients available on main page of this app.
+
+### How do I get set up? ###
+
+This paste utilizes PDO SQLite driver, well, at least for now :) and mbstrings.
+Tested php versions are 5.6.30 and 7.0.12. Paste uses **paste/paste.sqlite** file as db.
+
+Tested on apache/fcgid (windows) for dev and nginx/php-fpm for prod.
+
+Default installation assumes that paste runs as / app on site, but you can change it (BASEURL) in index.php.
+
+Nginx config snippet:
+```
+# limit paste size to ~ 200k
+client_max_body_size 256k;
+
+location /raw {
+ rewrite "^\/raw\/([a-z|A-Z]*)$" /index.php?$1;
+}
+
+rewrite "^/([a-z|A-Z]*)$" /index.php?$1;
+
+location / {
+ root /var/www/htdocs/empty;
+
+ index index.php;
+ location ~ \.php$ {
+ if ($request_method !~ ^(GET|HEAD|POST)$ ) {
+ return 499;
+ }
+
+ root /var/www/htdocs;
+ fastcgi_split_path_info ^(.+\.php)(/.+)$;
+ #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
+ fastcgi_index index.php;
+ include fastcgi.conf;
+ fastcgi_pass php;
+ }
+}
+```
+
+Database initialises automatically :)
+
+### Contribution guidelines ###
+
+Clean code, preferably with comments for some quirky places.
+
+### PasteBinIt configuration ###
+
+default pastebin site, __~/.pastebinit.xml__:
+```
+
+ http://your.site
+ Stephane Graber
+ stgraber@stgraber.org
+ text
+
+```
+and how to work with it __~/.pastebinit.d/your.site.conf__:
+```
+[pastebin]
+basename = your.site
+regexp = http://((([a-zA-Z0-9\-_\.]*)(your\.site)))
+
+[format]
+content = api_paste_code
+user = api_paste_name
+subdomain = api_paste_subdomain
+private = api_paste_private
+expiry = api_paste_expire_date
+format = api_paste_format
+email = api_paste_email
+page = page
+submit = submit
+regexp = regexp
+api_dev_key = api_dev_key
+api_option = api_option
+
+[defaults]
+submit = submit
+format = text
+private = 0
+expiry = 1M
+subdomain =
+email =
+api_dev_key = 253ce2f0a45140ee0a44ca99aa492260
+api_option = paste
+page = /
+regexp = (.*)
+```
+
+FYI difference between pastebin and paste are minimal:
+
+```diff
+diff -ruN pastebin.com.conf your.site.conf
+--- pastebin.com.conf
++++ your.site.conf
+@@ -1,6 +1,6 @@
+ [pastebin]
+-basename = pastebin.com
+-regexp = http://((([a-zA-Z0-9\-_\.]*)(pastebin\.com)))
++basename = your.site
++regexp = http://((([a-zA-Z0-9\-_\.]*)(your\.site)))
+
+ [format]
+ content = api_paste_code
+@@ -25,5 +25,5 @@
+ email =
+ api_dev_key = 253ce2f0a45140ee0a44ca99aa492260
+ api_option = paste
+-page = /api/api_post.php
++page = /
+ regexp = (.*)
+```
\ No newline at end of file
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..cc4223a
--- /dev/null
+++ b/index.php
@@ -0,0 +1,374 @@
+
+
+
+
+
+ Paste.
+
+
+ Paste
+
+
\n", $text);
+ }
+?>
+
+ Console client can be found here: e thanks sprunge.us for their client :)
+ More minimalist console client can be found here: d
+
+ 2015
+
+
+
+
+#!/bin/bash
+
+usage() {
+description | fmt -s >&2
+}
+
+description() {
+cat << HERE
+
+DESCRIPTION
+ Upload data and fetch URL from the pastebin
+
+USAGE
+ $0 filename.txt
+ $0 text string
+ $0 < filename.txt
+ piped_data | $0
+
+NOTES
+--------------------------------------------------------------------------
+* INPUT METHODS *
+$0 can accept piped data, STDIN redirection [&2
+ if [ "$*" ]; then
+ echo Arguments present... >&2
+ if [ -f "$*" ]; then
+ echo Uploading the contents of "$*"... >&2
+ cat "$*"
+ else
+ echo Uploading the text: \""$*"\"... >&2
+ echo "$*"
+ fi | curl -F "exs=<-"
+ else
+ echo No arguments found, printing USAGE and exiting. >&2
+ usage
+ fi
+else
+ echo Using input from a pipe or STDIN redirection... >&2
+ while read -r line ; do
+ echo $line
+ done | curl -F "exs=<-"
+fi
+
+#!/usr/bin/env bash
+
+if [[ "$1" == "--help" ]]; then
+ echo "Usage: $0 < file"
+ echo " echo foo | $0"
+elif [[ -f "$1" ]]; then
+ curl -F "exs=<-" "" <"$1"
+else
+ curl -F "exs=<-" ""
+fi
+
+exit 0
+';
+exec(
+ "CREATE TABLE IF NOT EXISTS paste (
+ id TEXT PRIMARY KEY,
+ paste TEXT,
+ time INTEGER,
+ etime INTEGER
+ )"
+ );
+
+ if($r === false) {
+ $e = $r->errorInfo();
+ showindex($e[2]);
+ }
+
+ $dbh = null;
+}
+
+function query_db($id) {
+ if (! file_exists(DBPATH)) {
+ init_db();
+ return false;
+ }
+
+ $dbh = new PDO("sqlite:" . DBPATH);
+ $sth = $dbh->query("SELECT paste FROM paste WHERE id='$id'");
+
+ if ($sth === false) {
+ $e = $r->errorInfo();
+ showindex($e[2]);
+ exit;
+ }
+
+ $sth->setFetchMode(PDO::FETCH_ASSOC);
+ $data = $sth->fetch();
+ $dbh = null;
+
+ if ($data === false) {
+ return($data);
+ } else {
+ if (isset($data['etime']) and ($data['etime'] < time())){
+ return false;
+ }
+
+ $data = $data['paste'];
+ return($data); # false if no data or no key in db
+ }
+}
+
+function store_data($paste) {
+ if (! file_exists(DBPATH)) { init_db(); }
+ $dbh = new PDO("sqlite:" . DBPATH);
+ $q = 0;
+
+ do {
+ if ($q > 100) { # assume key-value space depleted if we try more than 100 times
+ $q = false;
+ break;
+ }
+ $id = gen_id();
+ $q++;
+ } while (! $dbh->query("SELECT id FROM paste WHERE id='$id'"));
+
+ if($q === false) {
+ return('Storage depleted.');
+ }
+
+ $ctime = time();
+ $etime = $ctime + 14515200;
+
+ if(isset($_POST['etime'])) {
+ switch ($_POST['etime']) {
+ case '1': # 1 hour
+ $etime = $ctime + 3600;
+ break;
+
+ case '2': # 12 hours
+ $etime = $ctime + 43200;
+ break;
+
+ case '3': # 1 day
+ $etime = $ctime + 86400;
+ break;
+
+ case '4': # 1 week
+ $etime = $ctime + 604800;
+ break;
+
+ case '5': # 1 month
+ $etime = $ctime + 2419200;
+ break;
+
+ case '6': # 3 months
+ $etime = $ctime + 7257600;
+ break;
+
+ case '7': # 6 months
+ $etime = $ctime + 14515200;
+ break;
+
+ case '8': # 1 year
+ $etime = $ctime + 29030400;
+ break;
+
+ case '9': # 2 years
+ $etime = $ctime + 58060800;
+ break;
+
+ case '10': # 3 years
+ $etime = $ctime + 87091200;
+ break;
+
+ case '13': # forever
+ $etime = "null";
+ break;
+ }
+ }
+
+ $sth = $dbh->prepare("INSERT INTO paste VALUES('$id', '$paste', $ctime, $etime)");
+ $sth->execute();
+
+ if ($sth === false) {
+ $e = $sth->errorInfo();
+ showindex($e[2]);
+ exit;
+ }
+
+ $dbh = null;
+ return($id);
+}
+
+$text = '';
+
+if (($_SERVER['REQUEST_METHOD'] === 'GET') or ($_SERVER['REQUEST_METHOD'] === 'HEAD')) {
+ # substr returns empty string (boolean false) on error
+ $str = $_SERVER['REQUEST_URI']; $str = substr($str, mb_strlen(BASEURL, 'UTF-8'));
+
+ if ($str == 'e') {
+ eclient();
+ exit;
+ } elseif ($str == 'd') {
+ dclient();
+ exit;
+ }
+
+ # pastebin returns raw pate when paste' key prepended with /raw/, let's handle it
+ if (preg_match('/^raw\//', $str) == 1) {
+ $str = substr($str, mb_strlen('raw/', 'UTF-8'));
+ }
+
+ if ((mb_strlen($str, 'UTF-8') >= KEY_MIN) and ((mb_strlen($str, 'UTF-8') <= KEY_MAX))) {
+ if (preg_match('/^[a-z|A-Z]+$/', $str) == 1) {
+ $response = query_db($str);
+
+ if ($response === false) {
+ $text = 'No such paste.';
+ } else {
+ header('Content-Type: text/plain');
+ print base64_decode($response);
+ exit;
+ }
+ }
+ }
+
+} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
+ if (isset($_POST['exs']) and ($_POST['exs'] != '')) {
+ $text = APP_ADDRESS . store_data(base64_encode($_POST['exs']));
+ } elseif (isset($_POST['api_option'])){ # some pastebin API compatibility stuff
+ if ($_POST['api_option'] == 'paste') {
+ if ((isset($_POST['api_paste_code'])) and ($_POST['api_paste_code'] != '')) {
+ header('Content-Type: text/plain; charset=utf-8');
+ print mb_convert_encoding(APP_ADDRESS . store_data(base64_encode($_POST['api_paste_code'])), 'UTF-8', 'auto');
+ exit;
+ }
+ } elseif ($_POST['api_option'] == 'show_paste') {
+ if (isset($_POST['api_paste_key'])) {
+ $str = $_POST['api_paste_key'];
+
+ if ((mb_strlen($str, 'UTF-8') >= KEY_MIN) and ((mb_strlen($str, 'UTF-8') <= KEY_MAX))) {
+ if (preg_match('/^[a-z|A-Z]+$/', $str) == 1) {
+ $response = query_db($str);
+
+ if ($response === false) {
+ header('Content-Type: text/plain; charset=utf-8');
+ print "Bad API request, invalid permission to view this paste or invalid api_paste_key";
+ exit;
+ } else {
+ header('Content-Type: text/plain');
+ print base64_decode($response);
+ exit;
+ }
+ }
+ }
+ }
+ }
+ }
+} else {
+ # ???
+}
+
+showindex($text);
+?>
\ No newline at end of file