summaryrefslogtreecommitdiffstats
path: root/application
diff options
context:
space:
mode:
Diffstat (limited to 'application')
-rwxr-xr-x[-rw-r--r--]application/.htaccess0
-rwxr-xr-x[-rw-r--r--]application/cache/.htaccess0
-rwxr-xr-x[-rw-r--r--]application/cache/index.html0
-rw-r--r--application/config/.gitignore3
-rw-r--r--application/config/autoload.php4
-rw-r--r--application/config/config.php30
-rw-r--r--application/config/constants.php2
-rw-r--r--application/config/example/.gitignore1
-rw-r--r--application/config/example/config-local.php13
-rw-r--r--application/config/example/database.php (renamed from application/config/database.php)18
-rw-r--r--application/config/example/index.html10
-rw-r--r--application/config/example/memcache.php9
-rw-r--r--application/config/migration.php82
-rw-r--r--application/config/routes.php5
-rw-r--r--application/controllers/file.php704
-rwxr-xr-x[-rw-r--r--]application/controllers/index.html0
-rw-r--r--application/controllers/user.php234
-rw-r--r--application/controllers/welcome.php27
-rwxr-xr-x[-rw-r--r--]application/core/index.html0
-rwxr-xr-x[-rw-r--r--]application/errors/error_404.php0
-rwxr-xr-x[-rw-r--r--]application/errors/error_db.php0
-rwxr-xr-x[-rw-r--r--]application/errors/error_general.php34
-rwxr-xr-x[-rw-r--r--]application/errors/error_php.php0
-rwxr-xr-x[-rw-r--r--]application/errors/index.html0
-rw-r--r--application/helpers/filebin_helper.php259
-rwxr-xr-x[-rw-r--r--]application/helpers/index.html0
-rwxr-xr-x[-rw-r--r--]application/hooks/index.html0
-rwxr-xr-x[-rw-r--r--]application/index.html0
-rwxr-xr-x[-rw-r--r--]application/language/english/index.html0
-rw-r--r--application/libraries/MemcacheLibrary.php187
-rwxr-xr-x[-rw-r--r--]application/libraries/index.html0
-rwxr-xr-x[-rw-r--r--]application/logs/index.html0
-rw-r--r--application/migrations/001_add_files.php27
-rw-r--r--application/migrations/002_add_users.php46
-rw-r--r--application/migrations/003_add_referrers.php33
-rw-r--r--application/migrations/004_add_filesize.php22
-rw-r--r--application/migrations/005_drop_file_password.php21
-rw-r--r--application/migrations/006_add_username_index.php21
-rwxr-xr-x[-rw-r--r--]application/models/index.html0
-rw-r--r--application/models/mfile.php318
-rw-r--r--application/models/muser.php146
-rw-r--r--application/third_party/PasswordHash.php253
-rwxr-xr-x[-rw-r--r--]application/third_party/index.html0
-rw-r--r--application/views/file/client.php19
-rw-r--r--application/views/file/deleted.php14
-rw-r--r--application/views/file/file_info.php30
-rw-r--r--application/views/file/footer.php3
-rw-r--r--application/views/file/header.php28
-rw-r--r--application/views/file/html_footer.php5
-rw-r--r--application/views/file/html_header.php54
-rw-r--r--application/views/file/non_existent.php3
-rw-r--r--application/views/file/show_url.php6
-rw-r--r--application/views/file/too_big.php3
-rw-r--r--application/views/file/upload_error.php6
-rw-r--r--application/views/file/upload_form.php67
-rw-r--r--application/views/file/upload_history.php28
-rw-r--r--application/views/file_plaintext/client.php12
-rw-r--r--application/views/file_plaintext/deleted.php8
-rw-r--r--application/views/file_plaintext/footer.php0
-rw-r--r--application/views/file_plaintext/header.php0
-rw-r--r--application/views/file_plaintext/html_footer.php1
-rw-r--r--application/views/file_plaintext/html_header.php1
-rw-r--r--application/views/file_plaintext/non_existent.php1
-rw-r--r--application/views/file_plaintext/show_url.php2
-rw-r--r--application/views/file_plaintext/too_big.php2
-rw-r--r--application/views/file_plaintext/upload_error.php2
-rw-r--r--application/views/file_plaintext/upload_form.php18
-rw-r--r--application/views/file_plaintext/upload_history.php21
-rwxr-xr-x[-rw-r--r--]application/views/index.html0
l---------application/views/user/footer.php1
-rw-r--r--application/views/user/hash_password.php26
l---------application/views/user/header.php1
-rw-r--r--application/views/user/index.php1
-rw-r--r--application/views/user/invite.php15
-rw-r--r--application/views/user/login.php18
-rw-r--r--application/views/user/register.php26
-rw-r--r--application/views/user/registered.php3
-rw-r--r--application/views/welcome_message.php88
78 files changed, 2852 insertions, 170 deletions
diff --git a/application/.htaccess b/application/.htaccess
index 14249c50b..14249c50b 100644..100755
--- a/application/.htaccess
+++ b/application/.htaccess
diff --git a/application/cache/.htaccess b/application/cache/.htaccess
index 3418e55a6..3418e55a6 100644..100755
--- a/application/cache/.htaccess
+++ b/application/cache/.htaccess
diff --git a/application/cache/index.html b/application/cache/index.html
index c942a79ce..c942a79ce 100644..100755
--- a/application/cache/index.html
+++ b/application/cache/index.html
diff --git a/application/config/.gitignore b/application/config/.gitignore
new file mode 100644
index 000000000..bf68cb2ad
--- /dev/null
+++ b/application/config/.gitignore
@@ -0,0 +1,3 @@
+config-local.php
+database.php
+memcache.php
diff --git a/application/config/autoload.php b/application/config/autoload.php
index 53129c9c6..a471f3ab2 100644
--- a/application/config/autoload.php
+++ b/application/config/autoload.php
@@ -52,7 +52,7 @@ $autoload['packages'] = array();
| $autoload['libraries'] = array('database', 'session', 'xmlrpc');
*/
-$autoload['libraries'] = array();
+$autoload['libraries'] = array('database');
/*
@@ -64,7 +64,7 @@ $autoload['libraries'] = array();
| $autoload['helper'] = array('url', 'file');
*/
-$autoload['helper'] = array();
+$autoload['helper'] = array('url');
/*
diff --git a/application/config/config.php b/application/config/config.php
index 1ec65435e..3ffc367ca 100644
--- a/application/config/config.php
+++ b/application/config/config.php
@@ -248,7 +248,7 @@ $config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie'] = FALSE;
-$config['sess_use_database'] = FALSE;
+$config['sess_use_database'] = true;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_match_useragent'] = TRUE;
@@ -357,6 +357,34 @@ $config['rewrite_short_tags'] = FALSE;
*/
$config['proxy_ips'] = '';
+/*
+|--------------------------------------------------------------------------
+| Filebin
+|-------------------------------------------------------------------------
+|
+| upload_path should NOT be readable/served by the server, but only by
+| the script
+| sizes are in bytes
+| max_age in seconds
+|
+ */
+
+$config['upload_path'] = FCPATH.'data/uploads';
+$config['upload_max_size'] = 256*1024*1024;
+$config['upload_max_text_size'] = 2*1024*1024;
+
+// 0 disables deletion
+$config['upload_max_age'] = 60*60*24*5; // 5 days
+$config['invitations_max_age'] = 60*60*24*5; // 5 days
+
+// won't be deleted
+$config['small_upload_size'] = 1024*10; // 10KB
+
+$config['contact_me_url'] = ''; // ommiting this will remove the "contact me" line.
+
+if (file_exists(FCPATH.'application/config/config-local.php')) {
+ include FCPATH.'application/config/config-local.php';
+}
/* End of file config.php */
/* Location: ./application/config/config.php */
diff --git a/application/config/constants.php b/application/config/constants.php
index 4a879d360..1185dbca0 100644
--- a/application/config/constants.php
+++ b/application/config/constants.php
@@ -1,5 +1,7 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+putenv('HOME='.FCPATH);
+
/*
|--------------------------------------------------------------------------
| File and Directory Modes
diff --git a/application/config/example/.gitignore b/application/config/example/.gitignore
new file mode 100644
index 000000000..f9be8dfe0
--- /dev/null
+++ b/application/config/example/.gitignore
@@ -0,0 +1 @@
+!*
diff --git a/application/config/example/config-local.php b/application/config/example/config-local.php
new file mode 100644
index 000000000..d092d4206
--- /dev/null
+++ b/application/config/example/config-local.php
@@ -0,0 +1,13 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+
+/*
+ * Use this file to override any settings from config.php
+ */
+
+// set this to a 32char random string
+$config['encryption_key'] = '';
+
+// shouldn't be served by the webserver
+$config['upload_path'] = FCPATH.'data/uploads';
+
+$config['contact_me_url'] = '';
diff --git a/application/config/database.php b/application/config/example/database.php
index b4b34bf66..51b666b38 100644
--- a/application/config/database.php
+++ b/application/config/example/database.php
@@ -48,18 +48,18 @@
$active_group = 'default';
$active_record = TRUE;
-$db['default']['hostname'] = 'localhost';
-$db['default']['username'] = '';
-$db['default']['password'] = '';
-$db['default']['database'] = '';
-$db['default']['dbdriver'] = 'mysql';
-$db['default']['dbprefix'] = '';
+$db['default']['hostname'] = "localhost";
+$db['default']['username'] = "";
+$db['default']['password'] = "";
+$db['default']['database'] = "";
+$db['default']['dbdriver'] = "mysqli";
+$db['default']['dbprefix'] = "";
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
-$db['default']['cachedir'] = '';
-$db['default']['char_set'] = 'utf8';
-$db['default']['dbcollat'] = 'utf8_general_ci';
+$db['default']['cachedir'] = "";
+$db['default']['char_set'] = "utf8";
+$db['default']['dbcollat'] = "utf8_bin";
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
diff --git a/application/config/example/index.html b/application/config/example/index.html
new file mode 100644
index 000000000..c942a79ce
--- /dev/null
+++ b/application/config/example/index.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+ <title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/application/config/example/memcache.php b/application/config/example/memcache.php
new file mode 100644
index 000000000..a5bc7e3a8
--- /dev/null
+++ b/application/config/example/memcache.php
@@ -0,0 +1,9 @@
+<?php
+
+// this file is a config example for the codeigniter-memcache library
+// add this file to the your application's config directory
+$config["MEMCACHE_HOST"] = '127.0.0.1';
+$config["MEMCACHE_PORT"] = 11211;
+
+
+?>
diff --git a/application/config/migration.php b/application/config/migration.php
index afa264562..ad75f740c 100644
--- a/application/config/migration.php
+++ b/application/config/migration.php
@@ -1,41 +1,41 @@
-<?php defined('BASEPATH') OR exit('No direct script access allowed');
-/*
-|--------------------------------------------------------------------------
-| Enable/Disable Migrations
-|--------------------------------------------------------------------------
-|
-| Migrations are disabled by default but should be enabled
-| whenever you intend to do a schema migration.
-|
-*/
-$config['migration_enabled'] = FALSE;
-
-
-/*
-|--------------------------------------------------------------------------
-| Migrations version
-|--------------------------------------------------------------------------
-|
-| This is used to set migration version that the file system should be on.
-| If you run $this->migration->latest() this is the version that schema will
-| be upgraded / downgraded to.
-|
-*/
-$config['migration_version'] = 0;
-
-
-/*
-|--------------------------------------------------------------------------
-| Migrations Path
-|--------------------------------------------------------------------------
-|
-| Path to your migrations folder.
-| Typically, it will be within your application path.
-| Also, writing permission is required within the migrations path.
-|
-*/
-$config['migration_path'] = APPPATH . 'migrations/';
-
-
-/* End of file migration.php */
-/* Location: ./application/config/migration.php */ \ No newline at end of file
+<?php defined('BASEPATH') OR exit('No direct script access allowed');
+/*
+|--------------------------------------------------------------------------
+| Enable/Disable Migrations
+|--------------------------------------------------------------------------
+|
+| Migrations are disabled by default but should be enabled
+| whenever you intend to do a schema migration.
+|
+*/
+$config['migration_enabled'] = true;
+
+
+/*
+|--------------------------------------------------------------------------
+| Migrations version
+|--------------------------------------------------------------------------
+|
+| This is used to set migration version that the file system should be on.
+| If you run $this->migration->latest() this is the version that schema will
+| be upgraded / downgraded to.
+|
+*/
+$config['migration_version'] = 6;
+
+
+/*
+|--------------------------------------------------------------------------
+| Migrations Path
+|--------------------------------------------------------------------------
+|
+| Path to your migrations folder.
+| Typically, it will be within your application path.
+| Also, writing permission is required within the migrations path.
+|
+*/
+$config['migration_path'] = APPPATH . 'migrations/';
+
+
+/* End of file migration.php */
+/* Location: ./application/config/migration.php */
diff --git a/application/config/routes.php b/application/config/routes.php
index 5f9a58343..3ae891bfd 100644
--- a/application/config/routes.php
+++ b/application/config/routes.php
@@ -38,7 +38,10 @@
|
*/
-$route['default_controller'] = "welcome";
+$route['default_controller'] = "file";
+$route['user/(:any)'] = "user/$1";
+$route['file/(:any)'] = "file/$1";
+$route['(:any)'] = "file/index/$1";
$route['404_override'] = '';
diff --git a/application/controllers/file.php b/application/controllers/file.php
new file mode 100644
index 000000000..9616c0fc6
--- /dev/null
+++ b/application/controllers/file.php
@@ -0,0 +1,704 @@
+<?php
+/*
+ * Copyright 2009-2011 Florian "Bluewind" Pritz <bluewind@server-speed.net>
+ *
+ * Licensed under GPLv3
+ * (see COPYING for full license text)
+ *
+ */
+
+class File extends CI_Controller {
+
+ public $data = array();
+ public $var;
+
+ function __construct()
+ {
+ parent::__construct();
+
+ $this->var = new StdClass();
+
+ $this->load->library('migration');
+ if ( ! $this->migration->current()) {
+ show_error($this->migration->error_string());
+ }
+
+ $old_path = getenv("PATH");
+ putenv("PATH=$old_path:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin");
+
+ mb_internal_encoding('UTF-8');
+ $this->load->helper(array('form', 'filebin'));
+ $this->load->model('mfile');
+ $this->load->model('muser');
+
+ $this->var->latest_client = false;
+ if (file_exists(FCPATH.'data/client/latest')) {
+ $this->var->latest_client = trim(file_get_contents(FCPATH.'data/client/latest'));
+ }
+
+
+ if (is_cli_client()) {
+ $this->var->view_dir = "file_plaintext";
+ } else {
+ $this->var->view_dir = "file";
+ }
+
+ if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']) && $_SERVER['PHP_AUTH_USER'] && $_SERVER['PHP_AUTH_PW']) {
+ if (!$this->muser->login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])) {
+ // TODO: better message
+ echo "login failed.\n";
+ exit;
+ }
+ }
+
+ $this->data['username'] = $this->muser->get_username();
+ $this->data['title'] = "FileBin";
+ }
+
+ function index()
+ {
+ if ($this->input->is_cli_request()) {
+ echo "php index.php file <function> [arguments]\n";
+ echo "\n";
+ echo "Functions:\n";
+ echo " cron Cronjob\n";
+ echo " nuke_id <ID> Nukes all IDs sharing the same hash\n";
+ echo "\n";
+ echo "Functions that shouldn't have to be run:\n";
+ echo " clean_stale_files Remove files without database entries\n";
+ echo " update_file_sizes Update filesize in database\n";
+ exit;
+ }
+ // Try to guess what the user would like to do.
+ $id = $this->uri->segment(1);
+ if(isset($_FILES['file'])) {
+ $this->do_upload();
+ } elseif ($id != "file" && $this->mfile->id_exists($id)) {
+ $this->_download();
+ } elseif ($id && $id != "file") {
+ $this->_non_existent();
+ } else {
+ $this->upload_form();
+ }
+ }
+
+ function _download()
+ {
+ $id = $this->uri->segment(1);
+ $mode = urldecode($this->uri->segment(2));
+
+ $filedata = $this->mfile->get_filedata($id);
+ $file = $this->mfile->file($filedata['hash']);
+
+ if (!$this->mfile->valid_id($id)) {
+ $this->_non_existent();
+ return;
+ }
+
+ // don't allow unowned files to be downloaded
+ if ($filedata["user"] == 0) {
+ $this->_non_existent();
+ return;
+ }
+
+ // helps to keep traffic low when reloading
+ $etag = $filedata["hash"]."-".$filedata["date"];
+
+ // autodetect the mode for highlighting if the URL contains a / after the ID (/ID/)
+ // /ID/mode disables autodetection
+ $autodetect_mode = !$mode && substr_count(ltrim($this->uri->uri_string(), "/"), '/') >= 1;
+
+ if ($autodetect_mode) {
+ $mode = $this->mfile->get_highlight_mode($filedata["mimetype"], $filedata["filename"]);
+ }
+
+ // resolve aliases of modes
+ // this is mainly used for compatibility
+ $mode = $this->mfile->resolve_mode_alias($mode);
+
+ // create the qr code for /ID/
+ if ($mode == "qr") {
+ handle_etag($etag);
+ header("Content-disposition: inline; filename=\"".$id."_qr.png\"\n");
+ header("Content-Type: image/png\n");
+ passthru('qrencode -s 10 -o - '.escapeshellarg(site_url($id).'/'));
+ exit();
+ }
+
+ // user wants to the the plain file
+ if ($mode == 'plain') {
+ handle_etag($etag);
+ rangeDownload($file, $filedata["filename"], "text/plain");
+ exit();
+ }
+
+ if ($mode == 'info') {
+ $this->_display_info($id);
+ return;
+ }
+
+ // if there is no mimetype mapping we can't highlight it
+ $can_highlight = $this->mfile->can_highlight($filedata["mimetype"]);
+
+ $filesize_too_big = filesize($file) > $this->config->item('upload_max_text_size');
+
+ if (!$can_highlight || $filesize_too_big || !$mode) {
+ // prevent javascript from being executed and forbid frames
+ // this should allow us to serve user submitted HTML content without huge security risks
+ foreach (array("X-WebKit-CSP", "X-Content-Security-Policy") as $header_name) {
+ header("$header_name: allow 'none'; img-src *; media-src *; font-src *; style-src * 'unsafe-inline'; script-src 'none'; object-src *; frame-src 'none'; ");
+ }
+ handle_etag($etag);
+ rangeDownload($file, $filedata["filename"], $filedata["mimetype"]);
+ exit();
+ }
+
+ $this->data['title'] = htmlspecialchars($filedata['filename']);
+ $this->data['id'] = $id;
+
+ header("Content-Type: text/html\n");
+
+ $this->data['current_highlight'] = htmlspecialchars($mode);
+ $this->data['timeout'] = $this->mfile->get_timeout_string($id);
+
+ $this->load->view($this->var->view_dir.'/html_header', $this->data);
+
+ // highlight the file and chache the result
+ $this->load->library("MemcacheLibrary");
+ if (! $cached = $this->memcachelibrary->get($filedata['hash'].'_'.$mode)) {
+ ob_start();
+ if ($mode == "rmd") {
+ echo '<td class="markdownrender">'."\n";
+ passthru('perl '.FCPATH.'scripts/Markdown.pl '.escapeshellarg($file), $return_value);
+ } elseif ($mode == "ascii") {
+ echo '<td class="code"><pre class="text">'."\n";
+ passthru('perl '.FCPATH.'scripts/ansi2html '.escapeshellarg($file), $return_value);
+ echo "</pre>\n";
+ } else {
+ echo '<td class="numbers"><pre>';
+ // generate line numbers (links)
+ passthru('perl -ne \'print "<a href=\"#n$.\" id=\"n$.\">$.</a>\n"\' '.escapeshellarg($file), $return_value);
+ echo '</pre></td><td class="code">'."\n";
+ passthru('pygmentize -F codetagify -O encoding=guess,outencoding=utf8 -l '.escapeshellarg($mode).' -f html '.escapeshellarg($file), $return_value);
+ }
+ $cached = ob_get_contents();
+ ob_end_clean();
+ $this->memcachelibrary->set($filedata['hash'].'_'.$mode, $cached, 100);
+ }
+
+ if ($return_value != 0) {
+ show_error("Error trying to process the file. Either the lexer is unknown or something is broken.\n");
+ } else {
+ $this->output->append_output($cached);
+ }
+
+ $this->load->view($this->var->view_dir.'/html_footer', $this->data);
+ }
+
+ function _display_info($id)
+ {
+ $this->data["title"] .= " - Info $id";
+ $this->data["filedata"] = $this->mfile->get_filedata($id);
+ $this->data["id"] = $id;
+ $this->data['timeout'] = $this->mfile->get_timeout_string($id);
+
+ $this->load->view($this->var->view_dir.'/header', $this->data);
+ $this->load->view($this->var->view_dir.'/file_info', $this->data);
+ $this->load->view($this->var->view_dir.'/footer', $this->data);
+ }
+
+ function _non_existent()
+ {
+ $this->data["title"] .= " - Not Found";
+ $this->output->set_status_header(404);
+ $this->load->view($this->var->view_dir.'/header', $this->data);
+ $this->load->view($this->var->view_dir.'/non_existent', $this->data);
+ $this->load->view($this->var->view_dir.'/footer', $this->data);
+ }
+
+ function _show_url($id, $mode)
+ {
+ $redirect = false;
+
+ if (!$this->muser->logged_in()) {
+ $this->muser->require_session();
+ // keep the upload but require the user to login
+ $this->session->set_userdata("last_upload", array(
+ "id" => $id,
+ "mode" => $mode
+ ));
+ $this->session->set_flashdata("uri", "file/claim_id");
+ $this->muser->require_access();
+ }
+
+ if ($mode) {
+ $this->data['url'] = site_url($id).'/'.$mode;
+ } else {
+ $this->data['url'] = site_url($id).'/';
+
+ $filedata = $this->mfile->get_filedata($id);
+ $file = $this->mfile->file($filedata['hash']);
+ $type = $filedata['mimetype'];
+ $mode = $this->mfile->should_highlight($type);
+
+ // If we detected a highlightable file redirect,
+ // otherwise show the URL because browsers would just show a DL dialog
+ if ($mode) {
+ $redirect = true;
+ }
+ }
+
+ if (is_cli_client()) {
+ $redirect = false;
+ }
+ if ($redirect) {
+ redirect($this->data['url'], "location", 303);
+ } else {
+ $this->load->view($this->var->view_dir.'/header', $this->data);
+ $this->load->view($this->var->view_dir.'/show_url', $this->data);
+ $this->load->view($this->var->view_dir.'/footer', $this->data);
+ }
+ }
+
+ function client()
+ {
+ $this->data['title'] .= ' - Client';
+ if ($this->var->latest_client) {
+ $this->data['client_link'] = base_url().'data/client/fb-'.$this->var->latest_client.'.tar.gz';
+ } else {
+ $this->data['client_link'] = false;
+ }
+ $this->data['client_link_dir'] = base_url().'data/client/';
+ $this->data['client_link_deb'] = base_url().'data/client/deb/';
+ $this->data['client_link_slackware'] = base_url().'data/client/slackware/';
+
+ if (!is_cli_client()) {
+ $this->load->view($this->var->view_dir.'/header', $this->data);
+ }
+ $this->load->view($this->var->view_dir.'/client', $this->data);
+ if (!is_cli_client()) {
+ $this->load->view($this->var->view_dir.'/footer', $this->data);
+ }
+ }
+
+ function upload_form()
+ {
+ $this->data['title'] .= ' - Upload';
+ $this->data['small_upload_size'] = $this->config->item('small_upload_size');
+ $this->data['max_upload_size'] = $this->config->item('upload_max_size');
+ $this->data['upload_max_age'] = $this->config->item('upload_max_age')/60/60/24;
+ $this->data['contact_me_url'] = $this->config->item('contact_me_url');
+
+ $this->data['username'] = $this->muser->get_username();
+
+ $this->load->view($this->var->view_dir.'/header', $this->data);
+ $this->load->view($this->var->view_dir.'/upload_form', $this->data);
+ if (is_cli_client()) {
+ $this->client();
+ }
+ $this->load->view($this->var->view_dir.'/footer', $this->data);
+ }
+
+ // Allow CLI clients to query the server for the maxium filesize so they can
+ // stop the upload before wasting time and bandwith
+ function get_max_size()
+ {
+ echo $this->config->item('upload_max_size');
+ }
+
+ function upload_history()
+ {
+ $this->muser->require_access();
+
+ $user = $this->muser->get_userid();
+
+ $this->load->library("MemcacheLibrary");
+ if (! $cached = $this->memcachelibrary->get("history_".$this->var->view_dir."_".$user)) {
+ $query = array();
+ $lengths = array();
+
+ // key: database field name; value: display name
+ $fields = array(
+ "id" => "ID",
+ "filename" => "Filename",
+ "mimetype" => "Mimetype",
+ "date" => "Date",
+ "hash" => "Hash",
+ "filesize" => "Size"
+ );
+
+ $this->data['title'] .= ' - Upload history';
+ foreach($fields as $length_key => $value) {
+ $lengths[$length_key] = mb_strlen($value);
+ }
+
+ $query = $this->db->query("
+ SELECT ".implode(",", array_keys($fields))."
+ FROM files
+ WHERE user = ?
+ ORDER BY date
+ ", array($user))->result_array();
+
+ foreach($query as $key => $item) {
+ $query[$key]["date"] = date("r", $item["date"]);
+ $query[$key]["filesize"] = format_bytes($item["filesize"]);
+ if (is_cli_client()) {
+ // Keep track of longest string to pad plaintext output correctly
+ foreach($fields as $length_key => $value) {
+ $len = mb_strlen($query[$key][$length_key]);
+ if ($len > $lengths[$length_key]) {
+ $lengths[$length_key] = $len;
+ }
+ }
+ }
+ }
+
+ $total_size = $this->db->query("
+ SELECT sum(filesize) sum
+ FROM (
+ SELECT filesize
+ FROM files
+ WHERE user = ?
+ GROUP BY hash
+ ) sub
+ ", array($user))->row_array();
+
+ $this->data["query"] = $query;
+ $this->data["lengths"] = $lengths;
+ $this->data["fields"] = $fields;
+ $this->data["total_size"] = format_bytes($total_size["sum"]);
+
+ $cached = "";
+ $cached .= $this->load->view($this->var->view_dir.'/header', $this->data, true);
+ $cached .= $this->load->view($this->var->view_dir.'/upload_history', $this->data, true);
+ $cached .= $this->load->view($this->var->view_dir.'/footer', $this->data, true);
+
+ // disable for now. reenable if it causes too much load
+ //$this->memcachelibrary->set('history_'.$this->var->view_dir."_".$user, $cached, 42);
+ }
+
+ echo $cached;
+ }
+
+ function do_delete()
+ {
+ $this->muser->require_access();
+
+ $ids = $this->input->post("ids");
+ $errors = array();
+ $msgs = array();
+ $deleted_count = 0;
+ $total_count = 0;
+
+ if (!$ids) {
+ show_error("No IDs specified");
+ }
+
+ foreach ($ids as $id) {
+ $total_count++;
+
+ if (!$this->mfile->id_exists($id)) {
+ $errors[] = "'$id' didn't exist anymore.";
+ continue;
+ }
+
+ if ($this->mfile->delete_id($id)) {
+ $msgs[] = "'$id' has been removed.";
+ $deleted_count++;
+ } else {
+ $errors[] = "'$id' couldn't be deleted.";
+ }
+ }
+
+ $this->data["errors"] = $errors;
+ $this->data["msgs"] = $msgs;
+ $this->data["deleted_count"] = $deleted_count;
+ $this->data["total_count"] = $total_count;
+
+ $this->load->view($this->var->view_dir.'/header', $this->data);
+ $this->load->view($this->var->view_dir.'/deleted', $this->data);
+ $this->load->view($this->var->view_dir.'/footer', $this->data);
+ }
+
+ function delete()
+ {
+ $this->muser->require_access();
+
+ if (!is_cli_client()) {
+ echo "Not a listed cli client, please use the history to delete uploads.\n";
+ return;
+ }
+
+ $id = $this->uri->segment(3);
+ $this->data["id"] = $id;
+
+ if ($id && !$this->mfile->id_exists($id)) {
+ $this->output->set_status_header(404);
+ echo "Unknown ID '$id'.\n";
+ return;
+ }
+
+ if ($this->mfile->delete_id($id)) {
+ echo "$id has been deleted.\n";
+ } else {
+ echo "Deletion failed. Do you really own that file?\n";
+ }
+ }
+
+ // Handle pastes
+ function do_paste()
+ {
+ $content = $this->input->post("content");
+ $filesize = strlen($content);
+ $filename = "stdin";
+
+ if(!$content) {
+ $this->output->set_status_header(400);
+ $this->data["msg"] = "Nothing was pasted, content is empty.";
+ $this->load->view($this->var->view_dir.'/header', $this->data);
+ $this->load->view($this->var->view_dir.'/upload_error', $this->data);
+ $this->load->view($this->var->view_dir.'/footer');
+ return;
+ }
+
+ if ($filesize > $this->config->item('upload_max_size')) {
+ $this->output->set_status_header(413);
+ $this->load->view($this->var->view_dir.'/header', $this->data);
+ $this->load->view($this->var->view_dir.'/too_big');
+ $this->load->view($this->var->view_dir.'/footer');
+ return;
+ }
+
+ $id = $this->mfile->new_id();
+ $hash = md5($content);
+
+ $folder = $this->mfile->folder($hash);
+ file_exists($folder) || mkdir ($folder);
+ $file = $this->mfile->file($hash);
+
+ file_put_contents($file, $content);
+ chmod($file, 0600);
+ $this->mfile->add_file($hash, $id, $filename);
+ $this->_show_url($id, false);
+ }
+
+ // Handles uploaded files
+ function do_upload()
+ {
+ $extension = $this->input->post('extension');
+ if(!isset($_FILES['file']) || $_FILES['file']['error'] !== 0) {
+ $this->output->set_status_header(400);
+ $errors = array(
+ 0=>"There is no error, the file uploaded with success",
+ 1=>"The uploaded file exceeds the upload_max_filesize directive in php.ini",
+ 2=>"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form",
+ 3=>"The uploaded file was only partially uploaded",
+ 4=>"No file was uploaded",
+ 6=>"Missing a temporary folder"
+ );
+
+ $this->data["msg"] = "Unknown error.";
+
+ if (isset($_FILES["file"])) {
+ $this->data["msg"] = $errors[$_FILES['file']['error']];
+ }
+ $this->load->view($this->var->view_dir.'/header', $this->data);
+ $this->load->view($this->var->view_dir.'/upload_error', $this->data);
+ $this->load->view($this->var->view_dir.'/footer');
+ return;
+ }
+
+ $filesize = filesize($_FILES['file']['tmp_name']);
+ if ($filesize > $this->config->item('upload_max_size')) {
+ $this->output->set_status_header(413);
+ $this->load->view($this->var->view_dir.'/header', $this->data);
+ $this->load->view($this->var->view_dir.'/too_big');
+ $this->load->view($this->var->view_dir.'/footer');
+ return;
+ }
+
+ $id = $this->mfile->new_id();
+ $hash = md5_file($_FILES['file']['tmp_name']);
+
+ // work around a curl bug and allow the client to send the real filename base64 encoded
+ $filename = $this->input->post("filename");
+ if ($filename !== false) {
+ $filename = trim(base64_decode($filename, true), "\r\n\0\t\x0B");
+ }
+
+ // fall back if base64_decode failed
+ if ($filename === false) {
+ $filename = $_FILES['file']['name'];
+ }
+
+ $folder = $this->mfile->folder($hash);
+ file_exists($folder) || mkdir ($folder);
+ $file = $this->mfile->file($hash);
+
+ move_uploaded_file($_FILES['file']['tmp_name'], $file);
+ chmod($file, 0600);
+ $this->mfile->add_file($hash, $id, $filename);
+ $this->_show_url($id, $extension);
+ }
+
+ function claim_id()
+ {
+ $this->muser->require_access();
+
+ $last_upload = $this->session->userdata("last_upload");
+ $id = $last_upload["id"];
+
+ $filedata = $this->mfile->get_filedata($id);
+
+ if ($filedata["user"] != 0) {
+ show_error("Someone already owns '$id', can't reassign.");
+ }
+
+ $this->mfile->adopt($id);
+
+ $this->session->unset_userdata("last_upload");
+
+ $this->_show_url($id, $last_upload["mode"]);
+ }
+
+ /* Functions below this comment can only be run via the CLI
+ * `php index.php file <function name>`
+ */
+
+ // Removes old files
+ function cron()
+ {
+ if (!$this->input->is_cli_request()) return;
+
+ if ($this->config->item('upload_max_age') == 0) return;
+
+ $oldest_time = (time() - $this->config->item('upload_max_age'));
+ $oldest_session_time = (time() - $this->config->item("sess_expiration"));
+
+ $small_upload_size = $this->config->item('small_upload_size');
+
+ $query = $this->db->query('
+ SELECT hash, id, user
+ FROM files
+ WHERE date < ? OR (user = 0 AND date < ?)',
+ array($oldest_time, $oldest_session_time));
+
+ foreach($query->result_array() as $row) {
+ $file = $this->mfile->file($row['hash']);
+ if (!file_exists($file)) {
+ $this->db->query('DELETE FROM files WHERE id = ? LIMIT 1', array($row['id']));
+ continue;
+ }
+
+ if ($row["user"] == 0 || filesize($file) > $small_upload_size) {
+ if (filemtime($file) < $oldest_time) {
+ unlink($file);
+ $this->db->query('DELETE FROM files WHERE hash = ?', array($row['hash']));
+ } else {
+ $this->db->query('DELETE FROM files WHERE id = ? LIMIT 1', array($row['id']));
+ if ($this->mfile->stale_hash($row["hash"])) {
+ unlink($file);
+ }
+ }
+ }
+ }
+ }
+
+ /* remove files without database entries */
+ function clean_stale_files()
+ {
+ if (!$this->input->is_cli_request()) return;
+
+ $upload_path = $this->config->item("upload_path");
+ $outer_dh = opendir($upload_path);
+
+ while (($dir = readdir($outer_dh)) !== false) {
+ if (!is_dir($upload_path."/".$dir) || $dir == ".." || $dir == ".") {
+ continue;
+ }
+
+ $dh = opendir($upload_path."/".$dir);
+
+ $empty = true;
+
+ while (($file = readdir($dh)) !== false) {
+ if ($file == ".." || $file == ".") {
+ continue;
+ }
+
+ $query = $this->db->query("SELECT hash FROM files WHERE hash = ? LIMIT 1", array($file))->row_array();
+
+ if (empty($query)) {
+ unlink($upload_path."/".$dir."/".$file);
+ } else {
+ $empty = false;
+ }
+ }
+
+ closedir($dh);
+
+ if ($empty) {
+ rmdir($upload_path."/".$dir);
+ }
+ }
+ closedir($outer_dh);
+ }
+
+ function nuke_id()
+ {
+ if (!$this->input->is_cli_request()) return;
+
+ $id = $this->uri->segment(3);
+
+
+ $file_data = $this->mfile->get_filedata($id);
+
+ if (empty($file_data)) {
+ echo "unknown id \"$id\"\n";
+ return;
+ }
+
+ $hash = $file_data["hash"];
+
+ $this->db->query("
+ DELETE FROM files
+ WHERE hash = ?
+ ", array($hash));
+
+ unlink($this->mfile->file($hash));
+
+ echo "removed hash \"$hash\"\n";
+ }
+
+ function update_file_sizes()
+ {
+ if (!$this->input->is_cli_request()) return;
+
+ $chunk = 500;
+
+ $total = $this->db->count_all("files");
+
+ for ($limit = 0; $limit < $total; $limit += $chunk) {
+ $query = $this->db->query("
+ SELECT hash
+ FROM files
+ GROUP BY hash
+ LIMIT $limit, $chunk
+ ")->result_array();
+
+ foreach ($query as $key => $item) {
+ $hash = $item["hash"];
+ $filesize = intval(filesize($this->mfile->file($hash)));
+ $this->db->query("
+ UPDATE files
+ SET filesize = ?
+ WHERE hash = ?
+ ", array($filesize, $hash));
+ }
+ }
+
+
+ }
+}
+
+# vim: set noet:
diff --git a/application/controllers/index.html b/application/controllers/index.html
index c942a79ce..c942a79ce 100644..100755
--- a/application/controllers/index.html
+++ b/application/controllers/index.html
diff --git a/application/controllers/user.php b/application/controllers/user.php
new file mode 100644
index 000000000..ef79baa78
--- /dev/null
+++ b/application/controllers/user.php
@@ -0,0 +1,234 @@
+<?php
+
+class User extends CI_Controller {
+
+ public $data = array();
+ public $var;
+
+ function __construct()
+ {
+ parent::__construct();
+
+ $this->var = new StdClass();
+
+ $this->load->library('migration');
+ if ( ! $this->migration->current()) {
+ show_error($this->migration->error_string());
+ }
+
+ $this->load->model("muser");
+ $this->data["title"] = "FileBin";
+
+ $this->load->helper(array('form', 'filebin'));
+
+ $this->var->view_dir = "user/";
+ $this->data['username'] = $this->muser->get_username();
+ }
+
+ function index()
+ {
+ $this->data["username"] = $this->muser->get_username();
+
+ $this->load->view($this->var->view_dir.'header', $this->data);
+ $this->load->view($this->var->view_dir.'index', $this->data);
+ $this->load->view($this->var->view_dir.'footer', $this->data);
+ }
+
+ function login()
+ {
+ $this->muser->require_session();
+ $this->session->keep_flashdata("uri");
+
+ if ($this->input->post('process')) {
+ $username = $this->input->post('username');
+ $password = $this->input->post('password');
+
+ $result = $this->muser->login($username, $password);
+
+ if ($result !== true) {
+ $data['login_error'] = true;
+ $this->load->view($this->var->view_dir.'header', $this->data);
+ $this->load->view($this->var->view_dir.'login', $this->data);
+ $this->load->view($this->var->view_dir.'footer', $this->data);
+ } else {
+ $uri = $this->session->flashdata("uri");
+ if ($uri) {
+ redirect($uri);
+ } else {
+ redirect("/");
+ }
+ }
+ } else {
+ $this->load->view($this->var->view_dir.'header', $this->data);
+ $this->load->view($this->var->view_dir.'login', $this->data);
+ $this->load->view($this->var->view_dir.'footer', $this->data);
+ }
+ }
+
+ function create_invitation_key()
+ {
+ $this->muser->require_access();
+
+ $userid = $this->muser->get_userid();
+
+ // TODO: count both, invited users and key
+ $query = $this->db->query("
+ SELECT count(*) as count
+ FROM invitations
+ WHERE user = ?
+ ", array($userid))->row_array();
+
+ if ($query["count"] + 1 > 3) {
+ show_error("You can't create more invitation keys at this time.");
+ }
+
+ $key = random_alphanum(12, 16);
+
+ $this->db->query("
+ INSERT INTO invitations
+ (`key`, `user`, `date`)
+ VALUES (?, ?, ?)
+ ", array($key, $userid, time()));
+
+ redirect("user/invite");
+ }
+
+ function invite()
+ {
+ $this->muser->require_access();
+
+ $userid = $this->muser->get_userid();
+
+ $query = $this->db->query("
+ SELECT `key`
+ FROM invitations
+ WHERE user = ?
+ ", array($userid))->result_array();
+
+ $this->data["query"] = $query;
+
+ $this->load->view($this->var->view_dir.'header', $this->data);
+ $this->load->view($this->var->view_dir.'invite', $this->data);
+ $this->load->view($this->var->view_dir.'footer', $this->data);
+ }
+
+ function register()
+ {
+ $key = $this->uri->segment(3);
+ $process = $this->input->post("process");
+ $values = array(
+ "username" => "",
+ "email" => ""
+ );
+ $error = array();
+
+ $query = $this->db->query("
+ SELECT `user`, `key`
+ FROM invitations
+ WHERE `key` = ?
+ ", array($key))->row_array();
+
+ if (!isset($query["key"]) || $key != $query["key"]) {
+ show_error("Invalid invitation key.");
+ }
+
+ $referrer = $query["user"];
+
+ if ($process) {
+ $username = $this->input->post("username");
+ $email = $this->input->post("email");
+ $password = $this->input->post("password");
+ $password_confirm = $this->input->post("password_confirm");
+
+ if (!$username || strlen($username) > 32 || !preg_match("/^[a-z0-9]+$/", $username)) {
+ $error[]= "Invalid username (only up to 32 chars of a-z0-9 are allowed).";
+ }
+
+ $this->load->helper("email");
+ if (!valid_email($email)) {
+ $error[]= "Invalid email.";
+ }
+
+ if ($this->muser->username_exists($username)) {
+ $error[] = "Username already exists.";
+ }
+
+ if (!$password || $password != $password_confirm) {
+ $error[]= "No password or passwords don't match.";
+ }
+
+ if (empty($error)) {
+ $this->db->query("
+ INSERT INTO users
+ (`username`, `password`, `email`, `referrer`)
+ VALUES(?, ?, ?, ?)
+ ", array(
+ $username,
+ $this->muser->hash_password($password),
+ $email,
+ $referrer
+ ));
+ $this->db->query("
+ DELETE FROM invitations
+ WHERE `key` = ?
+ ", array($key));
+ $this->load->view($this->var->view_dir.'header', $this->data);
+ $this->load->view($this->var->view_dir.'registered', $this->data);
+ $this->load->view($this->var->view_dir.'footer', $this->data);
+ return;
+ } else {
+ $values["username"] = $username;
+ $values["email"] = $email;
+ }
+ }
+
+ $this->data["key"] = $key;
+ $this->data["values"] = $values;
+ $this->data["error"] = $error;
+
+ $this->load->view($this->var->view_dir.'header', $this->data);
+ $this->load->view($this->var->view_dir.'register', $this->data);
+ $this->load->view($this->var->view_dir.'footer', $this->data);
+ }
+
+ function logout()
+ {
+ $this->muser->logout();
+ redirect('/');
+ }
+
+ function hash_password()
+ {
+ $process = $this->input->post("process");
+ $password = $this->input->post("password");
+ $password_confirm = $this->input->post("password_confirm");
+ $this->data["hash"] = false;
+ $this->data["password"] = $password;
+
+ if ($process) {
+ if (!$password || $password != $password_confirm) {
+ $error[]= "No password or passwords don't match.";
+ } else {
+ $this->data["hash"] = $this->muser->hash_password($password);
+ }
+ }
+
+ $this->load->view($this->var->view_dir.'header', $this->data);
+ $this->load->view($this->var->view_dir.'hash_password', $this->data);
+ $this->load->view($this->var->view_dir.'footer', $this->data);
+ }
+
+ function cron()
+ {
+ if (!$this->input->is_cli_request()) return;
+
+ if ($this->config->item('invitations_max_age') == 0) return;
+
+ $oldest_time = (time() - $this->config->item('invitations_max_age'));
+
+ $this->db->query("
+ DELETE FROM invitations
+ WHERE date < ?
+ ", array($oldest_time));
+ }
+}
diff --git a/application/controllers/welcome.php b/application/controllers/welcome.php
deleted file mode 100644
index 21bef43d9..000000000
--- a/application/controllers/welcome.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
-
-class Welcome extends CI_Controller {
-
- /**
- * Index Page for this controller.
- *
- * Maps to the following URL
- * http://example.com/index.php/welcome
- * - or -
- * http://example.com/index.php/welcome/index
- * - or -
- * Since this controller is set as the default controller in
- * config/routes.php, it's displayed at http://example.com/
- *
- * So any other public methods not prefixed with an underscore will
- * map to /index.php/welcome/<method_name>
- * @see http://codeigniter.com/user_guide/general/urls.html
- */
- public function index()
- {
- $this->load->view('welcome_message');
- }
-}
-
-/* End of file welcome.php */
-/* Location: ./application/controllers/welcome.php */ \ No newline at end of file
diff --git a/application/core/index.html b/application/core/index.html
index c942a79ce..c942a79ce 100644..100755
--- a/application/core/index.html
+++ b/application/core/index.html
diff --git a/application/errors/error_404.php b/application/errors/error_404.php
index 792726a67..792726a67 100644..100755
--- a/application/errors/error_404.php
+++ b/application/errors/error_404.php
diff --git a/application/errors/error_db.php b/application/errors/error_db.php
index b396cda9f..b396cda9f 100644..100755
--- a/application/errors/error_db.php
+++ b/application/errors/error_db.php
diff --git a/application/errors/error_general.php b/application/errors/error_general.php
index fd63ce2c5..ae2bac76d 100644..100755
--- a/application/errors/error_general.php
+++ b/application/errors/error_general.php
@@ -1,3 +1,33 @@
+<?php
+
+// fancy error page only works if we can load helpers
+if (class_exists("CI_Controller") && !isset($GLOBALS["is_error_page"])) {
+ $title = "Error";
+ $GLOBALS["is_error_page"] = true;
+
+ $CI =& get_instance();
+ $CI->load->helper("filebin");
+ $CI->load->helper("url");
+
+ if (is_cli_client()) {
+ echo $heading."\n";
+ echo $message."\n";
+ exit();
+ }
+
+ include 'application/views/file/header.php';
+
+ ?>
+ <div class="error">
+ <h1><?php echo $heading; ?></h1>
+ <?php echo $message; ?>
+ </div>
+
+ <?php
+ include 'application/views/file/footer.php';
+} else {
+ // default CI error page
+?>
<!DOCTYPE html>
<html lang="en">
<head>
@@ -59,4 +89,6 @@ p {
<?php echo $message; ?>
</div>
</body>
-</html> \ No newline at end of file
+</html>
+<?php
+}
diff --git a/application/errors/error_php.php b/application/errors/error_php.php
index f085c2037..f085c2037 100644..100755
--- a/application/errors/error_php.php
+++ b/application/errors/error_php.php
diff --git a/application/errors/index.html b/application/errors/index.html
index c942a79ce..c942a79ce 100644..100755
--- a/application/errors/index.html
+++ b/application/errors/index.html
diff --git a/application/helpers/filebin_helper.php b/application/helpers/filebin_helper.php
new file mode 100644
index 000000000..2f073c902
--- /dev/null
+++ b/application/helpers/filebin_helper.php
@@ -0,0 +1,259 @@
+<?php
+
+function format_bytes($size)
+{
+ $suffixes = array('B', 'KiB', 'MiB', 'GiB', 'TiB' , 'PiB' , 'EiB', 'ZiB', 'YiB');
+ $boundary = 2048.0;
+
+ for ($suffix_pos = 0; $suffix_pos + 1 < count($suffixes); $suffix_pos++) {
+ if ($size <= $boundary && $size >= -$boundary) {
+ break;
+ }
+ $size /= 1024.0;
+ }
+
+ # don't print decimals for bytes
+ if ($suffix_pos != 0) {
+ return sprintf("%.2f%s", $size, $suffixes[$suffix_pos]);
+ } else {
+ return sprintf("%.0f%s", $size, $suffixes[$suffix_pos]);
+ }
+}
+
+// Original source: http://www.phpfreaks.com/forums/index.php?topic=198274.msg895468#msg895468
+function rangeDownload($file, $filename, $type)
+{
+ $fp = @fopen($file, 'r');
+
+ $size = filesize($file); // File size
+ $length = $size; // Content length
+ $start = 0; // Start byte
+ $end = $size - 1; // End byte
+ // Now that we've gotten so far without errors we send the accept range header
+ /* At the moment we only support single ranges.
+ * Multiple ranges requires some more work to ensure it works correctly
+ * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
+ *
+ * Multirange support annouces itself with:
+ * header('Accept-Ranges: bytes');
+ *
+ * Multirange content must be sent with multipart/byteranges mediatype,
+ * (mediatype = mimetype)
+ * as well as a boundry header to indicate the various chunks of data.
+ */
+ header("Accept-Ranges: 0-$length");
+ // header('Accept-Ranges: bytes');
+ // multipart/byteranges
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
+ if (isset($_SERVER['HTTP_RANGE']))
+ {
+ $c_start = $start;
+ $c_end = $end;
+ // Extract the range string
+ list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
+ // Make sure the client hasn't sent us a multibyte range
+ if (strpos($range, ',') !== false)
+ {
+ // (?) Shoud this be issued here, or should the first
+ // range be used? Or should the header be ignored and
+ // we output the whole content?
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ // (?) Echo some info to the client?
+ exit;
+ }
+ // If the range starts with an '-' we start from the beginning
+ // If not, we forward the file pointer
+ // And make sure to get the end byte if spesified
+ if ($range{0} == '-')
+ {
+ // The n-number of the last bytes is requested
+ $c_start = $size - substr($range, 1);
+ }
+ else
+ {
+ $range = explode('-', $range);
+ $c_start = $range[0];
+ $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
+ }
+ /* Check the range and make sure it's treated according to the specs.
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+ */
+ // End bytes can not be larger than $end.
+ $c_end = ($c_end > $end) ? $end : $c_end;
+ // Validate the requested range and return an error if it's not correct.
+ if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size)
+ {
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ // (?) Echo some info to the client?
+ exit;
+ }
+ $start = $c_start;
+ $end = $c_end;
+ $length = $end - $start + 1; // Calculate new content length
+ fseek($fp, $start);
+ header('HTTP/1.1 206 Partial Content');
+ // Notify the client the byte range we'll be outputting
+ header("Content-Range: bytes $start-$end/$size");
+ }
+ header("Content-Length: $length");
+ header("Content-disposition: inline; filename=\"".$filename."\"\n");
+ header("Content-Type: ".$type."\n");
+
+ // Start buffered download
+ $buffer = 1024 * 8;
+ while(!feof($fp) && ($p = ftell($fp)) <= $end)
+ {
+ if ($p + $buffer > $end)
+ {
+ // In case we're only outputtin a chunk, make sure we don't
+ // read past the length
+ $buffer = $end - $p + 1;
+ }
+ set_time_limit(0); // Reset time limit for big files
+ echo fread($fp, $buffer);
+ flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
+ }
+
+ fclose($fp);
+}
+
+function even_odd($reset = false)
+{
+ static $counter = 1;
+
+ if ($reset) {
+ $counter = 1;
+ }
+
+ if ($counter++%2 == 0) {
+ return 'even';
+ } else {
+ return 'odd';
+ }
+}
+
+// Source: http://hu.php.net/manual/en/function.str-pad.php#71558
+// This is a multibyte enabled str_pad
+function mb_str_pad($ps_input, $pn_pad_length, $ps_pad_string = " ", $pn_pad_type = STR_PAD_RIGHT, $ps_encoding = NULL)
+{
+ $ret = "";
+
+ if (is_null($ps_encoding))
+ $ps_encoding = mb_internal_encoding();
+
+ $hn_length_of_padding = $pn_pad_length - mb_strlen($ps_input, $ps_encoding);
+ $hn_psLength = mb_strlen($ps_pad_string, $ps_encoding); // pad string length
+
+ if ($hn_psLength <= 0 || $hn_length_of_padding <= 0) {
+ // Padding string equal to 0:
+ //
+ $ret = $ps_input;
+ }
+ else {
+ $hn_repeatCount = floor($hn_length_of_padding / $hn_psLength); // how many times repeat
+
+ if ($pn_pad_type == STR_PAD_BOTH) {
+ $hs_lastStrLeft = "";
+ $hs_lastStrRight = "";
+ $hn_repeatCountLeft = $hn_repeatCountRight = ($hn_repeatCount - $hn_repeatCount % 2) / 2;
+
+ $hs_lastStrLength = $hn_length_of_padding - 2 * $hn_repeatCountLeft * $hn_psLength; // the rest length to pad
+ $hs_lastStrLeftLength = $hs_lastStrRightLength = floor($hs_lastStrLength / 2); // the rest length divide to 2 parts
+ $hs_lastStrRightLength += $hs_lastStrLength % 2; // the last char add to right side
+
+ $hs_lastStrLeft = mb_substr($ps_pad_string, 0, $hs_lastStrLeftLength, $ps_encoding);
+ $hs_lastStrRight = mb_substr($ps_pad_string, 0, $hs_lastStrRightLength, $ps_encoding);
+
+ $ret = str_repeat($ps_pad_string, $hn_repeatCountLeft) . $hs_lastStrLeft;
+ $ret .= $ps_input;
+ $ret .= str_repeat($ps_pad_string, $hn_repeatCountRight) . $hs_lastStrRight;
+ }
+ else {
+ $hs_lastStr = mb_substr($ps_pad_string, 0, $hn_length_of_padding % $hn_psLength, $ps_encoding); // last part of pad string
+
+ if ($pn_pad_type == STR_PAD_LEFT)
+ $ret = str_repeat($ps_pad_string, $hn_repeatCount) . $hs_lastStr . $ps_input;
+ else
+ $ret = $ps_input . str_repeat($ps_pad_string, $hn_repeatCount) . $hs_lastStr;
+ }
+ }
+
+ return $ret;
+}
+
+function is_cli_client($override = null)
+{
+ static $is_cli = null;
+
+ if ($override !== null) {
+ $is_cli = $override;
+ }
+
+ if ($is_cli === null) {
+ $is_cli = false;
+ // official client uses "fb-client/$version" as useragent
+ $clients = array("fb-client", "libcurl", "pyfb", "curl/");
+ foreach ($clients as $client) {
+ if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], $client) !== false) {
+ $is_cli = true;
+ }
+ }
+ }
+ return $is_cli;
+}
+
+function random_alphanum($min_length, $max_length = null)
+{
+ $random = '';
+ $char_list = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ $char_list .= "abcdefghijklmnopqrstuvwxyz";
+ $char_list .= "1234567890";
+
+ if ($max_length === null) {
+ $max_length = $min_length;
+ }
+ $length = mt_rand($min_length, $max_length);
+
+ for($i = 0; $i < $max_length; $i++) {
+ if (strlen($random) == $length) break;
+ $random .= substr($char_list, mt_rand(0, strlen($char_list)), 1);
+ }
+ return $random;
+}
+
+function link_with_mtime($file)
+{
+ $link = base_url($file);
+
+ if (file_exists(FCPATH.$file)) {
+ $link .= "?".filemtime(FCPATH.$file);
+ }
+
+ return $link;
+}
+
+function handle_etag($etag)
+{
+ $etag = strtolower($etag);
+ $modified = true;
+
+ if(isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
+ $oldtag = trim(strtolower($_SERVER['HTTP_IF_NONE_MATCH']), '"');
+ if($oldtag == $etag) {
+ $modified = false;
+ } else {
+ $modified = true;
+ }
+ }
+
+ header('Etag: "'.$etag.'"');
+
+ if (!$modified) {
+ header("HTTP/1.1 304 Not Modified");
+ exit();
+ }
+}
+
+# vim: set noet:
diff --git a/application/helpers/index.html b/application/helpers/index.html
index c942a79ce..c942a79ce 100644..100755
--- a/application/helpers/index.html
+++ b/application/helpers/index.html
diff --git a/application/hooks/index.html b/application/hooks/index.html
index c942a79ce..c942a79ce 100644..100755
--- a/application/hooks/index.html
+++ b/application/hooks/index.html
diff --git a/application/index.html b/application/index.html
index c942a79ce..c942a79ce 100644..100755
--- a/application/index.html
+++ b/application/index.html
diff --git a/application/language/english/index.html b/application/language/english/index.html
index c942a79ce..c942a79ce 100644..100755
--- a/application/language/english/index.html
+++ b/application/language/english/index.html
diff --git a/application/libraries/MemcacheLibrary.php b/application/libraries/MemcacheLibrary.php
new file mode 100644
index 000000000..dc993b7a5
--- /dev/null
+++ b/application/libraries/MemcacheLibrary.php
@@ -0,0 +1,187 @@
+<?php
+
+/**
+* codeigniter-memcache v0.1
+*
+* codeigniter-memcache is a codeigniter library to work with memcached easily.
+*
+*
+* @file MemcacheLibrary.php
+* @copyright 2010 egnity - egnity.com
+* @author Emre Yilmaz <mail@emreyilmaz.me>
+* @license GNU General Public License
+* @version 0.1
+*/
+
+
+class MemcacheLibrary {
+
+ /**
+ * variable that holds memcached backend instance
+ *
+ * @var object
+ * @access public
+ */
+ public $memcachedInstance;
+
+ /**
+ * variable that holds servers for the memcache
+ *
+ * @var array
+ * @access public
+ */
+ public $servers = array();
+
+
+ /**
+ * main CodeIgniter instance
+ *
+ * @var object
+ * @access public
+ */
+ public $CI;
+
+ /**
+ * constructor function for the library
+ */
+ public function __construct() {
+
+ /* initialize memcached instance */
+ if(class_exists("Memcache")) {
+ $this->memcachedInstance = new Memcache();
+ } else {
+ throw new Exception(
+ "Memcached client doesn't exists in your PHP configuration"
+ );
+ }
+
+ /* load super CI instance */
+ $this->CI =& get_instance();
+
+ /* load default server info */
+ $this->CI->config->load("memcache");
+
+ /* connect to default server */
+ if($this->CI->config->item("MEMCACHE_HOST") && $this->CI->config->item("MEMCACHE_PORT") !== false) {
+ $this->addServer($this->CI->config->item("MEMCACHE_HOST"), $this->CI->config->item("MEMCACHE_PORT"));
+ }
+
+ }
+
+ /**
+ * adder function for the memcache servers
+ *
+ * @access public
+ * @return void
+ */
+ public function addServer($server, $port) {
+ $this->servers[] = array(
+ "server" => $server,
+ "port" => $port,
+ );
+
+ $this->memcachedInstance->addServer($server, $port);
+ }
+
+ /**
+ * gets related key from the memcache
+ *
+ * @access public
+ */
+ public function get($key) {
+ $this->logDebugMessage(sprintf("%s key requested from memcache", $key));
+
+ // hide notice if server is unreachable
+ $old_error_level = error_reporting();
+ error_reporting($old_error_level & ~E_NOTICE);
+
+ $ret = $this->memcachedInstance->get($key);
+
+ error_reporting($old_error_level);
+ return $ret;
+ }
+
+ /**
+ * sets related key to the memcache
+ *
+ * @access public
+ */
+ public function set($key, $value, $expire = null) {
+ $this->logDebugMessage(
+ sprintf("%s key set to memcache. (expire: %s)",$key, $expire)
+ );
+ return $this->memcachedInstance->set($key, $value, null, $expire);
+ }
+
+ /**
+ * deletes related key from the memcache
+ *
+ * @access public
+ */
+ public function delete($key) {
+ $this->logDebugMessage(sprintf("%s key deleted from memcache.", $key));
+ return $this->memcachedInstance->delete($key);
+ }
+
+ /**
+ * increments related key from the memcache
+ *
+ * @access public
+ */
+ public function increment($key, $offset = 1) {
+ $this->logDebugMessage(sprintf("%s key incremented %s times", $key, $offset));
+ return $this->memcachedInstance->increment($key, $offset);
+ }
+
+ /**
+ * decrements related key from the memcache
+ *
+ * @access public
+ */
+ public function decrement($key, $offset = 1) {
+ $this->logDebugMessage(sprintf("%s key decremented %s times", $key, $offset));
+ return $this->memcachedInstance->decrement($key, $offset);
+ }
+
+ /**
+ * gets running memcached servers.
+ *
+ * @access public
+ * @return array
+ */
+ public function getRunningServers() {
+ return $this->servers;
+ }
+
+ /**
+ * array of server statistics, one entry per server.
+ *
+ * @access public
+ * @return array
+ */
+ public function getStatistics() {
+ return $this->memcachedInstance->getStats();
+ }
+
+ /**
+ * Invalidates all items from the memcache.
+ *
+ * @access public
+ * @return boolean
+ */
+ public function flush($delay = 0) {
+ $this->logDebugMessage(sprintf("memcache flushed! (delay: %s)", $delay));
+ return $this->memcachedInstance->flush($delay);
+ }
+
+ /**
+ * logs the memcache actions to the codeigniter's main logging system.
+ *
+ * @access private
+ */
+ private function logDebugMessage($message) {
+ log_message("debug", $message);
+ }
+}
+
+# vim: set noet:
diff --git a/application/libraries/index.html b/application/libraries/index.html
index c942a79ce..c942a79ce 100644..100755
--- a/application/libraries/index.html
+++ b/application/libraries/index.html
diff --git a/application/logs/index.html b/application/logs/index.html
index c942a79ce..c942a79ce 100644..100755
--- a/application/logs/index.html
+++ b/application/logs/index.html
diff --git a/application/migrations/001_add_files.php b/application/migrations/001_add_files.php
new file mode 100644
index 000000000..f1f16ea3a
--- /dev/null
+++ b/application/migrations/001_add_files.php
@@ -0,0 +1,27 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+class Migration_Add_files extends CI_Migration {
+
+ public function up()
+ {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `files` (
+ `hash` varchar(32) CHARACTER SET ascii NOT NULL,
+ `id` varchar(6) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
+ `filename` varchar(256) COLLATE utf8_bin NOT NULL,
+ `password` varchar(40) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL,
+ `date` int(11) unsigned NOT NULL,
+ `mimetype` varchar(255) CHARACTER SET ascii NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `date` (`date`),
+ KEY `hash` (`hash`,`id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+ ");
+ }
+
+ public function down()
+ {
+ $this->dbforge->drop_table('files');
+ }
+}
diff --git a/application/migrations/002_add_users.php b/application/migrations/002_add_users.php
new file mode 100644
index 000000000..5675c77e9
--- /dev/null
+++ b/application/migrations/002_add_users.php
@@ -0,0 +1,46 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+class Migration_Add_users extends CI_Migration {
+
+ public function up()
+ {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `users` (
+ `id` int(8) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `username` varchar(32) COLLATE ascii_general_ci NOT NULL,
+ `password` varchar(60) COLLATE ascii_general_ci NOT NULL,
+ `email` varchar(255) COLLATE ascii_general_ci NOT NULL,
+ PRIMARY KEY (`id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+ ");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `ci_sessions` (
+ `session_id` varchar(40) NOT NULL DEFAULT '0',
+ `ip_address` varchar(16) NOT NULL DEFAULT '0',
+ `user_agent` varchar(120) NOT NULL,
+ `last_activity` int(10) unsigned NOT NULL DEFAULT '0',
+ `user_data` text NOT NULL,
+ PRIMARY KEY (`session_id`),
+ KEY `last_activity_idx` (`last_activity`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+ ");
+
+ $this->db->query("
+ ALTER TABLE `files`
+ ADD `user` INT(8) UNSIGNED NOT NULL DEFAULT '0',
+ ADD INDEX (`user`)
+ ");
+ }
+
+ public function down()
+ {
+ $this->dbforge->drop_table('users');
+ $this->dbforge->drop_table('ci_sessions');
+ $this->db->query("
+ ALTER TABLE `files`
+ DROP `user`
+ ");
+ }
+}
diff --git a/application/migrations/003_add_referrers.php b/application/migrations/003_add_referrers.php
new file mode 100644
index 000000000..524e92ff0
--- /dev/null
+++ b/application/migrations/003_add_referrers.php
@@ -0,0 +1,33 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+class Migration_Add_referrers extends CI_Migration {
+
+ public function up()
+ {
+ $this->db->query("
+ CREATE TABLE `invitations` (
+ `user` int(8) unsigned NOT NULL,
+ `key` varchar(16) CHARACTER SET ascii NOT NULL,
+ `date` int(11) unsigned NOT NULL,
+ PRIMARY KEY (`key`),
+ KEY `user` (`user`),
+ KEY `date` (`date`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
+ ");
+ $this->db->query("
+ ALTER TABLE `users`
+ ADD `referrer` INT(8) UNSIGNED NOT NULL DEFAULT '0'
+ ");
+ }
+
+ public function down()
+ {
+ $this->db->query("
+ ALTER TABLE `users`
+ DROP `referrer`
+ ");
+ $this->dbforge->drop_table('invitations');
+
+ }
+}
diff --git a/application/migrations/004_add_filesize.php b/application/migrations/004_add_filesize.php
new file mode 100644
index 000000000..d7a70223d
--- /dev/null
+++ b/application/migrations/004_add_filesize.php
@@ -0,0 +1,22 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+class Migration_Add_filesize extends CI_Migration {
+
+ public function up()
+ {
+ $this->db->query("
+ ALTER TABLE `files`
+ ADD `filesize` INT UNSIGNED NOT NULL
+ ");
+ }
+
+ public function down()
+ {
+ $this->db->query("
+ ALTER TABLE `files`
+ DROP `filesize`
+ ");
+
+ }
+}
diff --git a/application/migrations/005_drop_file_password.php b/application/migrations/005_drop_file_password.php
new file mode 100644
index 000000000..bf03490a8
--- /dev/null
+++ b/application/migrations/005_drop_file_password.php
@@ -0,0 +1,21 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+class Migration_Drop_file_password extends CI_Migration {
+
+ public function up()
+ {
+ $this->db->query("
+ ALTER TABLE `files`
+ DROP `password`;
+ ");
+ }
+
+ public function down()
+ {
+ $this->db->query("
+ ALTER TABLE `files`
+ ADD `password` varchar(40) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL;
+ ");
+ }
+}
diff --git a/application/migrations/006_add_username_index.php b/application/migrations/006_add_username_index.php
new file mode 100644
index 000000000..ea5e3ebc0
--- /dev/null
+++ b/application/migrations/006_add_username_index.php
@@ -0,0 +1,21 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+class Migration_Add_username_index extends CI_Migration {
+
+ public function up()
+ {
+ $this->db->query("
+ ALTER TABLE `users`
+ ADD UNIQUE `username` (`username`);
+ ");
+ }
+
+ public function down()
+ {
+ $this->db->query("
+ ALTER TABLE `users`
+ DROP INDEX `username`;
+ ");
+ }
+}
diff --git a/application/models/index.html b/application/models/index.html
index c942a79ce..c942a79ce 100644..100755
--- a/application/models/index.html
+++ b/application/models/index.html
diff --git a/application/models/mfile.php b/application/models/mfile.php
new file mode 100644
index 000000000..97c9ecfcd
--- /dev/null
+++ b/application/models/mfile.php
@@ -0,0 +1,318 @@
+<?php
+/*
+ * Copyright 2009-2011 Florian "Bluewind" Pritz <bluewind@server-speed.net>
+ *
+ * Licensed under GPLv3
+ * (see COPYING for full license text)
+ *
+ */
+
+class Mfile extends CI_Model {
+
+ function __construct()
+ {
+ parent::__construct();
+ $this->load->model("muser");
+ }
+
+ // Returns an unused ID
+ function new_id()
+ {
+ $id = random_alphanum(3,6);
+
+ if ($this->id_exists($id) || $id == 'file' || $id == 'user') {
+ return $this->new_id();
+ } else {
+ return $id;
+ }
+ }
+
+ function id_exists($id)
+ {
+ if(!$id) {
+ return false;
+ }
+
+ $sql = '
+ SELECT id
+ FROM `files`
+ WHERE `id` = ?
+ LIMIT 1';
+ $query = $this->db->query($sql, array($id));
+
+ if ($query->num_rows() == 1) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public function stale_hash($hash)
+ {
+ return $this->unused_file($hash);
+ }
+
+ function get_filedata($id)
+ {
+ $sql = '
+ SELECT hash, filename, mimetype, date, user, filesize
+ FROM `files`
+ WHERE `id` = ?
+ LIMIT 1';
+ $query = $this->db->query($sql, array($id));
+
+ if ($query->num_rows() == 1) {
+ $return = $query->result_array();
+ return $return[0];
+ } else {
+ return false;
+ }
+ }
+
+ // return the folder in which the file with $hash is stored
+ function folder($hash) {
+ return $this->config->item('upload_path').'/'.substr($hash, 0, 3);
+ }
+
+ // Returns the full path to the file with $hash
+ function file($hash) {
+ return $this->folder($hash).'/'.$hash;
+ }
+
+ // Add a hash to the DB
+ function add_file($hash, $id, $filename)
+ {
+ $userid = $this->muser->get_userid();
+
+ $mimetype = exec("perl ".FCPATH.'scripts/mimetype '.escapeshellarg($filename).' '.escapeshellarg($this->file($hash)));
+ $filesize = filesize($this->file($hash));
+ $query = $this->db->query('
+ INSERT INTO `files` (`hash`, `id`, `filename`, `user`, `date`, `mimetype`, `filesize`)
+ VALUES (?, ?, ?, ?, ?, ?, ?)',
+ array($hash, $id, $filename, $userid, time(), $mimetype, $filesize));
+ }
+
+ function adopt($id)
+ {
+ $userid = $this->muser->get_userid();
+
+ $this->db->query("
+ UPDATE files
+ SET user = ?
+ WHERE id = ?
+ ", array($userid, $id));
+ }
+
+ // remove old/invalid/broken IDs
+ function valid_id($id)
+ {
+ $filedata = $this->get_filedata($id);
+ if (!$filedata) {
+ return false;
+ }
+ $file = $this->file($filedata['hash']);
+
+ if (!file_exists($file)) {
+ if (isset($filedata["hash"])) {
+ $this->db->query('DELETE FROM files WHERE hash = ?', array($filedata['hash']));
+ }
+ return false;
+ }
+
+ // small files don't expire
+ if (filesize($file) <= $this->config->item("small_upload_size")) {
+ return true;
+ }
+
+ // files older than this should be removed
+ $remove_before = (time()-$this->config->item('upload_max_age'));
+
+ if ($filedata["date"] < $remove_before) {
+ // if the file has been uploaded multiple times the mtime is the time
+ // of the last upload
+ if (filemtime($file) < $remove_before) {
+ unlink($file);
+ $this->db->query('DELETE FROM files WHERE hash = ?', array($filedata['hash']));
+ } else {
+ $this->db->query('DELETE FROM files WHERE id = ? LIMIT 1', array($id));
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ function get_timeout_string($id)
+ {
+ $filedata = $this->get_filedata($id);
+ $file = $this->file($filedata["hash"]);
+
+ if (filesize($file) > $this->config->item("small_upload_size")) {
+ return date("r", $filedata["date"] + $this->config->item("upload_max_age"));
+ } else {
+ return "unknown";
+ }
+ }
+
+ private function unused_file($hash)
+ {
+ $sql = '
+ SELECT id
+ FROM `files`
+ WHERE `hash` = ?
+ LIMIT 1';
+ $query = $this->db->query($sql, array($hash));
+
+ if ($query->num_rows() == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function delete_id($id)
+ {
+ $this->muser->require_access();
+ $filedata = $this->get_filedata($id);
+ $userid = $this->muser->get_userid();
+
+ if(!$this->id_exists($id)) {
+ return false;
+ }
+
+ $sql = '
+ DELETE
+ FROM `files`
+ WHERE `id` = ?
+ AND user = ?
+ LIMIT 1';
+ $this->db->query($sql, array($id, $userid));
+
+ if($this->id_exists($id)) {
+ return false;
+ }
+
+ if($this->unused_file($filedata['hash'])) {
+ unlink($this->file($filedata['hash']));
+ @rmdir($this->folder($filedata['hash']));
+ }
+ return true;
+ }
+
+ function should_highlight($type)
+ {
+ if ($this->mime2mode($type)) return true;
+
+ return false;
+ }
+
+ // Allow certain types to be highlight without doing it automatically
+ function can_highlight($type)
+ {
+ $typearray = array(
+ 'image/svg+xml',
+ );
+ if (in_array($type, $typearray)) return true;
+
+ if ($this->mime2mode($type)) return true;
+
+ return false;
+ }
+
+ // Return the mode that should be used for highlighting
+ function get_highlight_mode($type, $filename)
+ {
+ $mode = $this->mime2mode($type);
+
+ // filename modes overwrite mime type mappings
+ $filename_mode = $this->filename2mode($filename);
+ if ($filename_mode) {
+ return $filename_mode;
+ }
+
+ return $mode;
+ }
+
+ // Map MIME types to modes needed for highlighting
+ private function mime2mode($type)
+ {
+ $typearray = array(
+ 'text/plain' => 'text',
+ 'text/plain-ascii' => 'ascii',
+ 'text/x-python' => 'python',
+ 'text/x-csrc' => 'c',
+ 'text/x-chdr' => 'c',
+ 'text/x-c++hdr' => 'c',
+ 'text/x-c++src' => 'cpp',
+ 'text/x-patch' => 'diff',
+ 'text/x-lua' => 'lua',
+ 'text/x-java' => 'java',
+ 'text/x-haskell' => 'haskell',
+ 'text/x-literate-haskell' => 'haskell',
+ 'text/x-subviewer' => 'bash',
+ 'text/x-scheme' => 'scheme',
+ 'text/x-makefile' => 'make',
+ #'text/x-log' => 'log',
+ 'text/html' => 'xml',
+ 'text/css' => 'css',
+ 'text/x-ocaml' => 'ocaml',
+ 'text/x-tcl' => 'tcl',
+ 'message/rfc822' => 'text',
+ #'image/svg+xml' => 'xml',
+ 'application/x-perl' => 'perl',
+ 'application/xml' => 'xml',
+ 'application/xml-dtd' => "xml",
+ 'application/xslt+xml' => "xml",
+ 'application/javascript' => 'javascript',
+ 'application/smil' => 'ocaml',
+ 'application/x-desktop' => 'text',
+ 'application/x-m4' => 'text',
+ 'application/x-awk' => 'text',
+ 'application/x-fluid' => 'text',
+ 'application/x-java' => 'java',
+ 'application/x-php' => 'php',
+ 'application/x-ruby' => 'ruby',
+ 'application/x-shellscript' => 'bash',
+ 'application/x-x509-ca-cert' => 'text',
+ 'application/mbox' => 'text',
+ 'application/x-genesis-rom' => 'text',
+ 'application/x-applix-spreadsheet' => 'actionscript'
+ );
+ if (array_key_exists($type, $typearray)) return $typearray[$type];
+
+ if (strpos($type, 'text/') === 0) return 'text';
+
+ # default
+ return false;
+ }
+
+ // Map special filenames to modes
+ private function filename2mode($name)
+ {
+ $namearray = array(
+ 'PKGBUILD' => 'bash',
+ '.vimrc' => 'vim'
+ );
+ if (array_key_exists($name, $namearray)) return $namearray[$name];
+
+ return false;
+ }
+
+ // Handle mode aliases
+ function resolve_mode_alias($alias)
+ {
+ if ($alias === false) return false;
+ $aliasarray = array(
+ 'py' => 'python',
+ 'sh' => 'bash',
+ 's' => 'asm',
+ 'pl' => 'perl'
+ );
+ if (array_key_exists($alias, $aliasarray)) return $aliasarray[$alias];
+
+ return $alias;
+ }
+
+}
+
+# vim: set noet:
diff --git a/application/models/muser.php b/application/models/muser.php
new file mode 100644
index 000000000..c29c04df6
--- /dev/null
+++ b/application/models/muser.php
@@ -0,0 +1,146 @@
+<?php
+
+class Muser extends CI_Model {
+ function __construct()
+ {
+ parent::__construct();
+
+ if ($this->has_session()) {
+ $this->session->keep_flashdata("uri");
+ }
+
+ $this->load->helper("filebin");
+ }
+
+ function has_session()
+ {
+ // checking $this doesn't work
+ $CI =& get_instance();
+ if (property_exists($CI, "session")) {
+ return true;
+ }
+
+ // Only load the session class if we already have a cookie that might need to be renewed.
+ // Otherwise we just create lots of stale sessions.
+ if (isset($_COOKIE[$this->config->item("sess_cookie_name")])) {
+ $this->load->library("session");
+ return true;
+ }
+
+ return false;
+ }
+
+ function require_session()
+ {
+ if (!$this->has_session()) {
+ $this->load->library("session");
+ }
+ }
+
+ function logged_in()
+ {
+ if ($this->has_session()) {
+ return $this->session->userdata('logged_in') == true;
+ }
+
+ return false;
+ }
+
+ function login($username, $password)
+ {
+ $this->require_session();
+ $query = $this->db->query('
+ SELECT username, id, password
+ FROM `users`
+ WHERE `username` = ?
+ ', array($username))->row_array();
+
+ if (!isset($query["username"]) || $query["username"] !== $username) {
+ return false;
+ }
+
+ if (!isset($query["password"])) {
+ return false;
+ }
+
+ if (crypt($password, $query["password"]) === $query["password"]) {
+ $this->session->set_userdata('logged_in', true);
+ $this->session->set_userdata('username', $username);
+ $this->session->set_userdata('userid', $query["id"]);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function logout()
+ {
+ $this->require_session();
+ $this->session->unset_userdata('logged_in');
+ $this->session->unset_userdata('username');
+ $this->session->sess_destroy();
+ }
+
+ function get_username()
+ {
+ if (!$this->logged_in()) {
+ return "";
+ }
+
+ return $this->session->userdata('username');
+ }
+
+ function get_userid()
+ {
+ if (!$this->logged_in()) {
+ return 0;
+ }
+
+ return $this->session->userdata("userid");
+ }
+
+ function require_access()
+ {
+ if ($this->logged_in()) {
+ return true;
+ } else {
+ if (is_cli_client()) {
+ echo "FileBin requires you to have an account, please go to the homepage for more information.\n";
+ exit();
+ } else {
+ $this->require_session();
+ if (!$this->session->userdata("flash:new:uri")) {
+ $this->session->set_flashdata("uri", $this->uri->uri_string());
+ }
+ redirect('user/login');
+ }
+ }
+ exit();
+ }
+
+ function username_exists($username)
+ {
+ $query = $this->db->query("
+ SELECT id
+ FROM users
+ WHERE username = ?
+ ", array($username));
+
+ if ($query->num_rows() > 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function hash_password($password)
+ {
+
+ require_once APPPATH."third_party/PasswordHash.php";
+
+ $hasher = new PasswordHash(9, false);
+ return $hasher->HashPassword($password);
+ }
+
+}
+
diff --git a/application/third_party/PasswordHash.php b/application/third_party/PasswordHash.php
new file mode 100644
index 000000000..12958c7f1
--- /dev/null
+++ b/application/third_party/PasswordHash.php
@@ -0,0 +1,253 @@
+<?php
+#
+# Portable PHP password hashing framework.
+#
+# Version 0.3 / genuine.
+#
+# Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in
+# the public domain. Revised in subsequent years, still public domain.
+#
+# There's absolutely no warranty.
+#
+# The homepage URL for this framework is:
+#
+# http://www.openwall.com/phpass/
+#
+# Please be sure to update the Version line if you edit this file in any way.
+# It is suggested that you leave the main version number intact, but indicate
+# your project name (after the slash) and add your own revision information.
+#
+# Please do not change the "private" password hashing method implemented in
+# here, thereby making your hashes incompatible. However, if you must, please
+# change the hash type identifier (the "$P$") to something different.
+#
+# Obviously, since this code is in the public domain, the above are not
+# requirements (there can be none), but merely suggestions.
+#
+class PasswordHash {
+ var $itoa64;
+ var $iteration_count_log2;
+ var $portable_hashes;
+ var $random_state;
+
+ function PasswordHash($iteration_count_log2, $portable_hashes)
+ {
+ $this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+
+ if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
+ $iteration_count_log2 = 8;
+ $this->iteration_count_log2 = $iteration_count_log2;
+
+ $this->portable_hashes = $portable_hashes;
+
+ $this->random_state = microtime();
+ if (function_exists('getmypid'))
+ $this->random_state .= getmypid();
+ }
+
+ function get_random_bytes($count)
+ {
+ $output = '';
+ if (is_readable('/dev/urandom') &&
+ ($fh = @fopen('/dev/urandom', 'rb'))) {
+ $output = fread($fh, $count);
+ fclose($fh);
+ }
+
+ if (strlen($output) < $count) {
+ $output = '';
+ for ($i = 0; $i < $count; $i += 16) {
+ $this->random_state =
+ md5(microtime() . $this->random_state);
+ $output .=
+ pack('H*', md5($this->random_state));
+ }
+ $output = substr($output, 0, $count);
+ }
+
+ return $output;
+ }
+
+ function encode64($input, $count)
+ {
+ $output = '';
+ $i = 0;
+ do {
+ $value = ord($input[$i++]);
+ $output .= $this->itoa64[$value & 0x3f];
+ if ($i < $count)
+ $value |= ord($input[$i]) << 8;
+ $output .= $this->itoa64[($value >> 6) & 0x3f];
+ if ($i++ >= $count)
+ break;
+ if ($i < $count)
+ $value |= ord($input[$i]) << 16;
+ $output .= $this->itoa64[($value >> 12) & 0x3f];
+ if ($i++ >= $count)
+ break;
+ $output .= $this->itoa64[($value >> 18) & 0x3f];
+ } while ($i < $count);
+
+ return $output;
+ }
+
+ function gensalt_private($input)
+ {
+ $output = '$P$';
+ $output .= $this->itoa64[min($this->iteration_count_log2 +
+ ((PHP_VERSION >= '5') ? 5 : 3), 30)];
+ $output .= $this->encode64($input, 6);
+
+ return $output;
+ }
+
+ function crypt_private($password, $setting)
+ {
+ $output = '*0';
+ if (substr($setting, 0, 2) == $output)
+ $output = '*1';
+
+ $id = substr($setting, 0, 3);
+ # We use "$P$", phpBB3 uses "$H$" for the same thing
+ if ($id != '$P$' && $id != '$H$')
+ return $output;
+
+ $count_log2 = strpos($this->itoa64, $setting[3]);
+ if ($count_log2 < 7 || $count_log2 > 30)
+ return $output;
+
+ $count = 1 << $count_log2;
+
+ $salt = substr($setting, 4, 8);
+ if (strlen($salt) != 8)
+ return $output;
+
+ # We're kind of forced to use MD5 here since it's the only
+ # cryptographic primitive available in all versions of PHP
+ # currently in use. To implement our own low-level crypto
+ # in PHP would result in much worse performance and
+ # consequently in lower iteration counts and hashes that are
+ # quicker to crack (by non-PHP code).
+ if (PHP_VERSION >= '5') {
+ $hash = md5($salt . $password, TRUE);
+ do {
+ $hash = md5($hash . $password, TRUE);
+ } while (--$count);
+ } else {
+ $hash = pack('H*', md5($salt . $password));
+ do {
+ $hash = pack('H*', md5($hash . $password));
+ } while (--$count);
+ }
+
+ $output = substr($setting, 0, 12);
+ $output .= $this->encode64($hash, 16);
+
+ return $output;
+ }
+
+ function gensalt_extended($input)
+ {
+ $count_log2 = min($this->iteration_count_log2 + 8, 24);
+ # This should be odd to not reveal weak DES keys, and the
+ # maximum valid value is (2**24 - 1) which is odd anyway.
+ $count = (1 << $count_log2) - 1;
+
+ $output = '_';
+ $output .= $this->itoa64[$count & 0x3f];
+ $output .= $this->itoa64[($count >> 6) & 0x3f];
+ $output .= $this->itoa64[($count >> 12) & 0x3f];
+ $output .= $this->itoa64[($count >> 18) & 0x3f];
+
+ $output .= $this->encode64($input, 3);
+
+ return $output;
+ }
+
+ function gensalt_blowfish($input)
+ {
+ # This one needs to use a different order of characters and a
+ # different encoding scheme from the one in encode64() above.
+ # We care because the last character in our encoded string will
+ # only represent 2 bits. While two known implementations of
+ # bcrypt will happily accept and correct a salt string which
+ # has the 4 unused bits set to non-zero, we do not want to take
+ # chances and we also do not want to waste an additional byte
+ # of entropy.
+ $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+
+ $output = '$2a$';
+ $output .= chr(ord('0') + $this->iteration_count_log2 / 10);
+ $output .= chr(ord('0') + $this->iteration_count_log2 % 10);
+ $output .= '$';
+
+ $i = 0;
+ do {
+ $c1 = ord($input[$i++]);
+ $output .= $itoa64[$c1 >> 2];
+ $c1 = ($c1 & 0x03) << 4;
+ if ($i >= 16) {
+ $output .= $itoa64[$c1];
+ break;
+ }
+
+ $c2 = ord($input[$i++]);
+ $c1 |= $c2 >> 4;
+ $output .= $itoa64[$c1];
+ $c1 = ($c2 & 0x0f) << 2;
+
+ $c2 = ord($input[$i++]);
+ $c1 |= $c2 >> 6;
+ $output .= $itoa64[$c1];
+ $output .= $itoa64[$c2 & 0x3f];
+ } while (1);
+
+ return $output;
+ }
+
+ function HashPassword($password)
+ {
+ $random = '';
+
+ if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
+ $random = $this->get_random_bytes(16);
+ $hash =
+ crypt($password, $this->gensalt_blowfish($random));
+ if (strlen($hash) == 60)
+ return $hash;
+ }
+
+ if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
+ if (strlen($random) < 3)
+ $random = $this->get_random_bytes(3);
+ $hash =
+ crypt($password, $this->gensalt_extended($random));
+ if (strlen($hash) == 20)
+ return $hash;
+ }
+
+ if (strlen($random) < 6)
+ $random = $this->get_random_bytes(6);
+ $hash =
+ $this->crypt_private($password,
+ $this->gensalt_private($random));
+ if (strlen($hash) == 34)
+ return $hash;
+
+ # Returning '*' on error is safe here, but would _not_ be safe
+ # in a crypt(3)-like function used _both_ for generating new
+ # hashes and for validating passwords against existing hashes.
+ return '*';
+ }
+
+ function CheckPassword($password, $stored_hash)
+ {
+ $hash = $this->crypt_private($password, $stored_hash);
+ if ($hash[0] == '*')
+ $hash = crypt($password, $stored_hash);
+
+ return $hash == $stored_hash;
+ }
+}
+
+?>
diff --git a/application/third_party/index.html b/application/third_party/index.html
index c942a79ce..c942a79ce 100644..100755
--- a/application/third_party/index.html
+++ b/application/third_party/index.html
diff --git a/application/views/file/client.php b/application/views/file/client.php
new file mode 100644
index 000000000..b507c5f1e
--- /dev/null
+++ b/application/views/file/client.php
@@ -0,0 +1,19 @@
+<p><b>Shell:</b></p>
+<pre>
+curl -n -F "file=@/home/user/foo" <?php echo site_url(); ?> (binary safe)
+cat file | curl -n -F "file=@-;filename=stdin" <?php echo site_url(); ?> (binary safe)
+</pre>
+<p><b>Client:</b></p>
+<p>Development (git): <a href="http://git.server-speed.net/users/flo/fb/">http://git.server-speed.net/users/flo/fb/</a><br />
+<?php if($client_link) {?>Latest release: <a href="<?php echo $client_link; ?>"><?php echo $client_link; ?></a>.<br /><?php }; ?>
+GPG sigs, older versions: <a href="<?php echo $client_link_dir; ?>"><?php echo $client_link_dir; ?></a>
+</p>
+<p>To authenticate add the following to your ~/.netrc:</p>
+<pre>
+machine paste.xinu.at login my_username password my_secret_password
+</pre>
+<p><b>Packages:</b><br />
+Arch Linux: pacman -S fb-client<br />
+Debian: <a href="<?php echo $client_link_deb; ?>"><?php echo $client_link_deb; ?></a><br />
+Slackware: <a href="<?php echo $client_link_slackware; ?>"><?php echo $client_link_slackware; ?></a></p>
+
diff --git a/application/views/file/deleted.php b/application/views/file/deleted.php
new file mode 100644
index 000000000..ef02398d9
--- /dev/null
+++ b/application/views/file/deleted.php
@@ -0,0 +1,14 @@
+<div class="center">
+ <?php if (!empty($errors)) {
+ echo "<p>";
+ echo implode("<br />\n", $errors);
+ echo "</p>";
+ } ?>
+ <?php if (!empty($msgs)) {
+ echo "<p>";
+ echo implode("<br />\n", $msgs);
+ echo "</p>";
+ } ?>
+
+ <p><?php echo $deleted_count; ?> of <?php echo $total_count; ?> deleted.</p>
+</div>
diff --git a/application/views/file/file_info.php b/application/views/file/file_info.php
new file mode 100644
index 000000000..779ece854
--- /dev/null
+++ b/application/views/file/file_info.php
@@ -0,0 +1,30 @@
+<div class="center">
+ <?php if($filedata): ?>
+ <table style="margin: auto">
+ <tr>
+ <td class="title">ID</td>
+ <td class="text"><a href="<?php echo site_url($id); ?>/"><?php echo $id; ?></a></td>
+ </tr>
+ <tr>
+ <td class="title">Filename</td>
+ <td class="text"><?php echo $filedata["filename"]; ?></td>
+ </tr>
+ <tr>
+ <td class="title">Date of upload</td>
+ <td class="text"><?php echo date("r", $filedata["date"]); ?></td>
+ </tr>
+ <tr>
+ <td class="title">Date of removal</td>
+ <td class="text"><?php echo $timeout; ?></td>
+ </tr>
+ <tr>
+ <td class="title">Size</td>
+ <td class="text"><?php echo format_bytes($filedata["filesize"]); ?></td>
+ </tr>
+ <tr>
+ <td class="title">Mimetype</td>
+ <td class="text"><?php echo $filedata["mimetype"]; ?></td>
+ </tr>
+ </table>
+ <?php endif; ?>
+</div>
diff --git a/application/views/file/footer.php b/application/views/file/footer.php
new file mode 100644
index 000000000..eda863585
--- /dev/null
+++ b/application/views/file/footer.php
@@ -0,0 +1,3 @@
+ </div>
+</body>
+</html>
diff --git a/application/views/file/header.php b/application/views/file/header.php
new file mode 100644
index 000000000..3029e4579
--- /dev/null
+++ b/application/views/file/header.php
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+ <title><?php echo isset($title) ? $title : ''; ?></title>
+ <link rel="stylesheet" type="text/css" href="<?php echo link_with_mtime("/data/default.css"); ?>" media="screen" />
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <meta name="robots" content="noindex,nofollow" />
+</head>
+
+<body>
+ <div class="top">
+ <?php echo anchor('file/index', 'New'); ?> |
+ <?php echo anchor('file/upload_history', 'History'); ?> |
+ <?php echo anchor('user/invite', 'Invite'); ?>
+
+ <?php if(!isset($is_error_page)) { ?>
+ <div class="right">
+ <?php if(isset($username) && $username) { ?>
+ <?=anchor("user/logout", "Logout"); ?>
+ <?php } else { ?>
+ <?=anchor("user/login", "Login"); ?>
+ <?php } ?>
+ </div>
+ <?php } ?>
+ </div>
+
+ <div class="content">
diff --git a/application/views/file/html_footer.php b/application/views/file/html_footer.php
new file mode 100644
index 000000000..ddc460a39
--- /dev/null
+++ b/application/views/file/html_footer.php
@@ -0,0 +1,5 @@
+ </td>
+ </tr>
+ </table>
+ </body>
+</html>
diff --git a/application/views/file/html_header.php b/application/views/file/html_header.php
new file mode 100644
index 000000000..cd2116ada
--- /dev/null
+++ b/application/views/file/html_header.php
@@ -0,0 +1,54 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title><?php echo $title; ?></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <link rel="stylesheet" type="text/css" href="<?php echo link_with_mtime("/data/paste.css"); ?>" />
+<?php if (file_exists(FCPATH."/data/paste-$current_highlight.css")) {?>
+ <link rel="stylesheet" type="text/css" href="<?php echo link_with_mtime("/data/paste-$current_highlight.css"); ?>" />
+<?php } ?>
+ </head>
+ <body>
+ <div class="top_bar">
+ <a class="raw_link no" href="<?php echo site_url(); ?>">New</a> |
+ <a class="raw_link no" href="<?php echo site_url($id); ?>">Raw</a> |
+ <a class="raw_link no" href="<?php echo site_url($id."/plain"); ?>">Plain</a> |
+ <a class="raw_link no" href="<?php echo site_url($id."/info"); ?>">Info</a> |
+ Currently: <?php echo $current_highlight; ?> |
+ Timeout: <?php echo $timeout; ?>
+ <div style="float:right;">
+ <a class="raw_link no" href="<?php echo site_url($id)."/"; ?>">Code</a> |
+ <a class="raw_link no" href="<?php echo site_url($id."/rmd"); ?>">Render Markdown</a>
+ </div>
+ </div>
+<script type="text/javascript">
+/* <![CDATA[ */
+function update_anchor_highlight() {
+ var anchor = window.location.hash.substr(1);
+ var element = document.getElementById("highlight_line");
+ if (element) {
+ element.parentNode.removeChild(element);
+ }
+
+ anchor = document.getElementById(anchor);
+ if (!anchor) {
+ return;
+ }
+ var newElement = document.createElement("div");
+ newElement.setAttribute("id", "highlight_line");
+ newElement.textContent=" ";
+ anchor.parentNode.insertBefore(newElement, anchor.nextSibling);
+}
+
+if ("onhashchange" in window) {
+ window.onload = function () {
+ update_anchor_highlight();
+ }
+ window.onhashchange = function () {
+ update_anchor_highlight();
+ }
+}
+/* ]]> */
+</script>
+ <table class="content">
+ <tr>
diff --git a/application/views/file/non_existent.php b/application/views/file/non_existent.php
new file mode 100644
index 000000000..13d8c6950
--- /dev/null
+++ b/application/views/file/non_existent.php
@@ -0,0 +1,3 @@
+<div class="center">
+ <p>I'm sorry, but the requested file doesn't exist.</p>
+</div>
diff --git a/application/views/file/show_url.php b/application/views/file/show_url.php
new file mode 100644
index 000000000..3c08ed952
--- /dev/null
+++ b/application/views/file/show_url.php
@@ -0,0 +1,6 @@
+<div class="center">
+ <p>
+ You can get your file here:<br />
+ <a href="<?php echo $url; ?>"><?php echo $url; ?></a><br />
+ </p>
+</div>
diff --git a/application/views/file/too_big.php b/application/views/file/too_big.php
new file mode 100644
index 000000000..5b970a4c8
--- /dev/null
+++ b/application/views/file/too_big.php
@@ -0,0 +1,3 @@
+<div class="center">
+ <p>Sorry, the file you uploaded is too big.</p>
+</div>
diff --git a/application/views/file/upload_error.php b/application/views/file/upload_error.php
new file mode 100644
index 000000000..83968eec2
--- /dev/null
+++ b/application/views/file/upload_error.php
@@ -0,0 +1,6 @@
+<div class="center">
+ <p>
+ An error occurred while uploading.<br />
+ <?php echo $msg; ?>
+ </p>
+</div>
diff --git a/application/views/file/upload_form.php b/application/views/file/upload_form.php
new file mode 100644
index 000000000..20fb1a3d8
--- /dev/null
+++ b/application/views/file/upload_form.php
@@ -0,0 +1,67 @@
+<? if ($username) { ?>
+<div class="center">
+ <?php echo form_open_multipart('file/do_upload'); ?>
+ <p>
+ File: <input type="file" id="file" name="file" size="30" />
+ <input type="submit" value="Upload" id="upload_button" name="process" />
+ </p>
+ </form>
+ <p><b>OR</b></p>
+ <?php echo form_open_multipart('file/do_paste'); ?>
+ <p>
+ <textarea id="textarea" name="content" cols="80" rows="20"></textarea><br />
+ <input type="submit" value="Paste" name="process" />
+ </p>
+ </form>
+ <script type="text/javascript">
+ /* <![CDATA[ */
+ var max_upload_size = "<?php echo $max_upload_size; ?>";
+ /* ]]> */
+ </script>
+ <script type="text/javascript" src="<?php echo link_with_mtime("/data/js/upload_form.js"); ?>"></script>
+</div>
+<? } else { ?>
+You have to <?=anchor("user/login", "log in"); ?> to be able to upload/paste.
+<div id="login-form">
+ <?=form_open("user/login"); ?>
+ <input type="text" name="username" />
+ <input type="password" name="password" />
+ <input type="submit" value="Login" name="process" />
+ </form>
+</div>
+<? } ?>
+<br />
+<p>Uploads/pastes are deleted after <?php echo $upload_max_age; ?> days<?php if($small_upload_size > 0): ?>
+ unless they are smaller than <?php echo format_bytes($small_upload_size); ?>
+ <?php endif; ?>. Maximum upload size is <?php echo format_bytes($max_upload_size); ?></p>
+<h2>Features</h2>
+<p>For shell uploading/pasting and download information for the client go to <a href="<?php echo site_url("file/client"); ?>"><?php echo site_url("file/client"); ?></a></p>
+<p>You can use the <?php echo anchor("file/upload_history", "history"); ?> to find old uploads.</p>
+<p>How to link your pastes:</p>
+<ul>
+ <li><span class="example">/&lt;ID&gt;/</span> automatically highlight the paste</li>
+ <li><span class="example">/&lt;ID&gt;</span> set the detected MIME type and let the browser do the rest</li>
+ <li><span class="example">/&lt;ID&gt;/plain</span> force the MIME type to be text/plain</li>
+ <li><span class="example">/&lt;ID&gt;/&lt;file extension&gt;</span> override auto detection and use the supplied file extension or language name for highlighting</li>
+ <li><span class="example">/&lt;ID&gt;/qr</span> display a qr code containing a link to <span class="example">/&lt;ID&gt;/</span></li>
+ <li><span class="example">/&lt;ID&gt;/rmd</span> convert markdown to HTML</li>
+ <li><span class="example">/&lt;ID&gt;/ascii</span> convert text with ANSI (shell) escape codes to HTML</li>
+ <li><span class="example">/&lt;ID&gt;/info</span> display some information about the ID</li>
+</ul>
+<p>If your upload is not detected as text, only
+<span class="example">/&lt;ID&gt;/qr</span>,
+<span class="example">/&lt;ID&gt;/plain</span> and
+<span class="example">/&lt;ID&gt;/info</span>
+will work as above and all others will simply return the file with the detected MIME type.</p>
+
+<h2>Information</h2>
+<p>This website's primary goal is aiding developers, power users, students and alike in solving problems, debugging software, sharing their configuration, etc. It is not intended to distribute confidential or harmful information, scripts or software.</p>
+
+<p>If you believe you deserve an account, ask someone who is already using this service to <?=anchor("user/invite", "invite"); ?> you.</p>
+
+<?php if($contact_me_url) {?><p>If you experience any problems feel free to <a href="<?php echo $contact_me_url; ?>">contact me</a>.</p>
+<br /><?php }; ?>
+<div class="small">
+ <p>Icons by <a href="http://p.yusukekamiyamane.com/">Yusuke Kamiyamane</a></p>
+ <p>This service is provided without warranty of any kind and may not be used to distribute copyrighted content.</p>
+</div>
diff --git a/application/views/file/upload_history.php b/application/views/file/upload_history.php
new file mode 100644
index 000000000..41b055792
--- /dev/null
+++ b/application/views/file/upload_history.php
@@ -0,0 +1,28 @@
+<?php echo form_open("file/do_delete"); ?>
+ <table class="results">
+ <tr>
+ <th></th>
+ <th>ID</th>
+ <th>Filename</th>
+ <th>Mimetype
+ <th>Date</th>
+ <th>Hash</th>
+ <th>Size</th>
+ </tr>
+
+ <?php foreach($query as $key => $item): ?>
+ <tr class="<?php echo even_odd(); ?>">
+ <td><input type="checkbox" name="ids[<?php echo $item["id"]; ?>]" value="<?php echo $item["id"]; ?>" /></td>
+ <td><a href="<?php echo site_url("/".$item["id"]); ?>/"><?php echo $item["id"]; ?></a></td>
+ <td><?php echo htmlspecialchars($item["filename"]); ?></td>
+ <td><?php echo $item["mimetype"]; ?></td>
+ <td><?php echo $item["date"]; ?></td>
+ <td><?php echo $item["hash"]; ?></td>
+ <td><?php echo $item["filesize"]; ?></td>
+ </tr>
+ <?php endforeach; ?>
+ </table>
+ <input type="submit" value="Delete checked" name="process" />
+</form>
+
+<p>Total sum of your distinct uploads: <?php echo $total_size; ?>.</p>
diff --git a/application/views/file_plaintext/client.php b/application/views/file_plaintext/client.php
new file mode 100644
index 000000000..b37fd81bd
--- /dev/null
+++ b/application/views/file_plaintext/client.php
@@ -0,0 +1,12 @@
+Shell (binary safe):
+ curl -n -F "file=@/home/user/foo" <?php echo site_url()."\n"; ?>
+ cat file | curl -n -F "file=@-;filename=stdin" <?php echo site_url()."\n"; ?>
+
+Client:
+Development (git): http://git.server-speed.net/users/flo/fb
+Latest release: <?php echo $client_link."\n"; ?>
+GPG sigs, older versions: <?php echo $client_link_dir."\n"; ?>
+
+To authenticate add the following to your ~/.netrc:
+ machine paste.xinu.at login my_username password my_secret_password
+
diff --git a/application/views/file_plaintext/deleted.php b/application/views/file_plaintext/deleted.php
new file mode 100644
index 000000000..347766092
--- /dev/null
+++ b/application/views/file_plaintext/deleted.php
@@ -0,0 +1,8 @@
+<?php if (!empty($errors)) {
+ echo implode("\n", $errors);
+} ?>
+<?php if (!empty($msgs)) {
+ echo implode("\n", $msgs);
+} ?>
+
+<?php echo $deleted_count; ?> of <?php echo $total_count; ?> deleted.
diff --git a/application/views/file_plaintext/footer.php b/application/views/file_plaintext/footer.php
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/application/views/file_plaintext/footer.php
diff --git a/application/views/file_plaintext/header.php b/application/views/file_plaintext/header.php
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/application/views/file_plaintext/header.php
diff --git a/application/views/file_plaintext/html_footer.php b/application/views/file_plaintext/html_footer.php
new file mode 100644
index 000000000..d46a93ce4
--- /dev/null
+++ b/application/views/file_plaintext/html_footer.php
@@ -0,0 +1 @@
+<?php include "application/views/file/html_footer.php"; ?>
diff --git a/application/views/file_plaintext/html_header.php b/application/views/file_plaintext/html_header.php
new file mode 100644
index 000000000..5cc4c40a7
--- /dev/null
+++ b/application/views/file_plaintext/html_header.php
@@ -0,0 +1 @@
+<?php include "application/views/file/html_header.php"; ?>
diff --git a/application/views/file_plaintext/non_existent.php b/application/views/file_plaintext/non_existent.php
new file mode 100644
index 000000000..7da92e954
--- /dev/null
+++ b/application/views/file_plaintext/non_existent.php
@@ -0,0 +1 @@
+I'm sorry, but the requested file doesn't exist.
diff --git a/application/views/file_plaintext/show_url.php b/application/views/file_plaintext/show_url.php
new file mode 100644
index 000000000..bb94d7422
--- /dev/null
+++ b/application/views/file_plaintext/show_url.php
@@ -0,0 +1,2 @@
+<?php echo $url; ?>
+
diff --git a/application/views/file_plaintext/too_big.php b/application/views/file_plaintext/too_big.php
new file mode 100644
index 000000000..d27a0295c
--- /dev/null
+++ b/application/views/file_plaintext/too_big.php
@@ -0,0 +1,2 @@
+Sorry, the file you uploaded is too big.
+
diff --git a/application/views/file_plaintext/upload_error.php b/application/views/file_plaintext/upload_error.php
new file mode 100644
index 000000000..c86c56911
--- /dev/null
+++ b/application/views/file_plaintext/upload_error.php
@@ -0,0 +1,2 @@
+An error occurred while uploading. <?php echo $msg; ?>
+
diff --git a/application/views/file_plaintext/upload_form.php b/application/views/file_plaintext/upload_form.php
new file mode 100644
index 000000000..7fe3aa801
--- /dev/null
+++ b/application/views/file_plaintext/upload_form.php
@@ -0,0 +1,18 @@
+Uploads/pastes are deleted after <?php echo $upload_max_age; ?> days<?php if($small_upload_size > 0): ?> unless they are smaller than <?php echo format_bytes($small_upload_size); ?><?php endif; ?>.
+Maximum upload size is <?php echo format_bytes($max_upload_size); ?>.
+
+How to link your uploads:
+ - "/<ID>/" automatically highlight the uploads
+ - "/<ID>" set the detected MIME type and let the browser do the rest
+ - "/<ID>/plain" force the MIME type to be text/plain
+ - "/<ID>/<file extension>" override auto detection and use the supplied
+ file extension or language name for highlighting
+ - "/<ID>/qr" display a qr code containing a link to /<ID>/
+ - "/<ID>/rmd" convert markdown to HTML
+ - "/<ID>/ascii" convert text with ANSI (shell) escape codes to HTML
+ - "/<ID>/info" display some information about the ID
+
+If your upload is not detected as text, only "/<ID>/qr", "/<ID>/plain"
+and "/<ID>/info" will work as above and all others will simply return
+the file with the detected MIME type.
+
diff --git a/application/views/file_plaintext/upload_history.php b/application/views/file_plaintext/upload_history.php
new file mode 100644
index 000000000..b4dbf6091
--- /dev/null
+++ b/application/views/file_plaintext/upload_history.php
@@ -0,0 +1,21 @@
+<?php
+echo
+ mb_str_pad($fields["id"], $lengths["id"])." | "
+ .mb_str_pad($fields["filename"], $lengths["filename"])." | "
+ .mb_str_pad($fields["mimetype"], $lengths["mimetype"])." | "
+ .mb_str_pad($fields["date"], $lengths["date"])." | "
+ .mb_str_pad($fields["hash"], $lengths["hash"])." | "
+ .mb_str_pad($fields["filesize"], $lengths["filesize"])."\n";
+
+foreach($query as $key => $item) {
+ echo
+ mb_str_pad($item["id"], $lengths["id"])." | "
+ .mb_str_pad($item["filename"], $lengths["filename"])." | "
+ .mb_str_pad($item["mimetype"], $lengths["mimetype"])." | "
+ .$item["date"]." | "
+ .$item["hash"]." | "
+ .$item["filesize"]."\n";
+}
+?>
+
+Total sum of your distinct uploads: <?php echo $total_size; ?>.
diff --git a/application/views/index.html b/application/views/index.html
index c942a79ce..c942a79ce 100644..100755
--- a/application/views/index.html
+++ b/application/views/index.html
diff --git a/application/views/user/footer.php b/application/views/user/footer.php
new file mode 120000
index 000000000..e3a4d3fca
--- /dev/null
+++ b/application/views/user/footer.php
@@ -0,0 +1 @@
+../file/footer.php \ No newline at end of file
diff --git a/application/views/user/hash_password.php b/application/views/user/hash_password.php
new file mode 100644
index 000000000..a0aa88ce5
--- /dev/null
+++ b/application/views/user/hash_password.php
@@ -0,0 +1,26 @@
+<?php
+if (!empty($error)) {
+ echo "<p>";
+ echo implode("<br />\n", $error);
+ echo "</p>";
+}
+
+if ($hash) {
+ echo "<p>Result (this hash uses a random salt, so it will be different each time you submit this form):<br />$hash</p>\n";
+}
+?>
+<?php echo form_open('user/hash_password'); ?>
+ <table>
+ <tr>
+ <td>Password</td>
+ <td> <input type="password" name="password" /></td>
+ </tr><tr>
+ <td>Confirm password</td>
+ <td> <input type="password" name="password_confirm" /></td>
+ </tr><tr>
+ <td></td>
+ <td><input type="submit" value="Hash it" name="process" /></td>
+ </tr>
+ </table>
+</form>
+
diff --git a/application/views/user/header.php b/application/views/user/header.php
new file mode 120000
index 000000000..7b5e4d759
--- /dev/null
+++ b/application/views/user/header.php
@@ -0,0 +1 @@
+../file/header.php \ No newline at end of file
diff --git a/application/views/user/index.php b/application/views/user/index.php
new file mode 100644
index 000000000..891ecc083
--- /dev/null
+++ b/application/views/user/index.php
@@ -0,0 +1 @@
+Momentan eingeloggt als "<?php echo $username; ?>".<br />
diff --git a/application/views/user/invite.php b/application/views/user/invite.php
new file mode 100644
index 000000000..5be8b48a3
--- /dev/null
+++ b/application/views/user/invite.php
@@ -0,0 +1,15 @@
+<?php echo form_open('user/create_invitation_key'); ?>
+ <input type="submit" value="Create new key" name="process" />
+</form>
+
+<p>
+You are free to invite anyone you want to, but please keep in
+mind that if this person violates the rules and is banned, your account will also be disabled.
+</p>
+
+<p>Unused invitation keys:</p>
+<p>
+<?php foreach($query as $key => $item): ?>
+ <?php echo anchor("user/register/".$item["key"], $item["key"]); ?><br />
+<?php endforeach; ?>
+</p>
diff --git a/application/views/user/login.php b/application/views/user/login.php
new file mode 100644
index 000000000..ca6f01b88
--- /dev/null
+++ b/application/views/user/login.php
@@ -0,0 +1,18 @@
+<?php
+if (isset($login_error)) {
+ echo '<font style="color: rgb(238, 51, 51);">The entered credentials are invalid.</font>';
+} ?>
+
+<?php echo form_open('user/login'); ?>
+ <table>
+ <tr>
+ <td>Username:</td>
+ <td><input type="text" name="username" /></td>
+ </tr>
+ <tr>
+ <td>Password:</td>
+ <td><input type="password" name="password" /></td>
+ </tr>
+ </table>
+ <input type="submit" value="Login" name="process" />
+</form>
diff --git a/application/views/user/register.php b/application/views/user/register.php
new file mode 100644
index 000000000..78af46e96
--- /dev/null
+++ b/application/views/user/register.php
@@ -0,0 +1,26 @@
+<?php if (!empty($error)) {
+ echo "<p>";
+ echo implode("<br />\n", $error);
+ echo "</p>";
+} ?>
+<?php echo form_open('user/register/'.$key); ?>
+ <table>
+ <tr>
+ <td>Username</td>
+ <td> <input type="text" name="username" value="<?=$values["username"]; ?>" /></td>
+ </tr><tr>
+ <td>Email</td>
+ <td> <input type="text" name="email" value="<?=$values["email"]; ?>" /></td>
+ </tr><tr>
+ <td>Password</td>
+ <td> <input type="password" name="password" /></td>
+ </tr><tr>
+ <td>Confirm password</td>
+ <td> <input type="password" name="password_confirm" /></td>
+ </tr><tr>
+ <td></td>
+ <td><input type="submit" value="Register" name="process" /></td>
+ </tr>
+ </table>
+</form>
+
diff --git a/application/views/user/registered.php b/application/views/user/registered.php
new file mode 100644
index 000000000..f13006aae
--- /dev/null
+++ b/application/views/user/registered.php
@@ -0,0 +1,3 @@
+<div class="center">
+ <p>Your account has been created, you may log in now.</p>
+</div>
diff --git a/application/views/welcome_message.php b/application/views/welcome_message.php
deleted file mode 100644
index 0bf5a8d2e..000000000
--- a/application/views/welcome_message.php
+++ /dev/null
@@ -1,88 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>Welcome to CodeIgniter</title>
-
- <style type="text/css">
-
- ::selection{ background-color: #E13300; color: white; }
- ::moz-selection{ background-color: #E13300; color: white; }
- ::webkit-selection{ background-color: #E13300; color: white; }
-
- body {
- background-color: #fff;
- margin: 40px;
- font: 13px/20px normal Helvetica, Arial, sans-serif;
- color: #4F5155;
- }
-
- a {
- color: #003399;
- background-color: transparent;
- font-weight: normal;
- }
-
- h1 {
- color: #444;
- background-color: transparent;
- border-bottom: 1px solid #D0D0D0;
- font-size: 19px;
- font-weight: normal;
- margin: 0 0 14px 0;
- padding: 14px 15px 10px 15px;
- }
-
- code {
- font-family: Consolas, Monaco, Courier New, Courier, monospace;
- font-size: 12px;
- background-color: #f9f9f9;
- border: 1px solid #D0D0D0;
- color: #002166;
- display: block;
- margin: 14px 0 14px 0;
- padding: 12px 10px 12px 10px;
- }
-
- #body{
- margin: 0 15px 0 15px;
- }
-
- p.footer{
- text-align: right;
- font-size: 11px;
- border-top: 1px solid #D0D0D0;
- line-height: 32px;
- padding: 0 10px 0 10px;
- margin: 20px 0 0 0;
- }
-
- #container{
- margin: 10px;
- border: 1px solid #D0D0D0;
- -webkit-box-shadow: 0 0 8px #D0D0D0;
- }
- </style>
-</head>
-<body>
-
-<div id="container">
- <h1>Welcome to CodeIgniter!</h1>
-
- <div id="body">
- <p>The page you are looking at is being generated dynamically by CodeIgniter.</p>
-
- <p>If you would like to edit this page you'll find it located at:</p>
- <code>application/views/welcome_message.php</code>
-
- <p>The corresponding controller for this page is found at:</p>
- <code>application/controllers/welcome.php</code>
-
- <p>If you are exploring CodeIgniter for the very first time, you should start by reading the <a href="user_guide/">User Guide</a>.</p>
- </div>
-
- <p class="footer">Page rendered in <strong>{elapsed_time}</strong> seconds</p>
-</div>
-
-</body>
-</html> \ No newline at end of file