X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=index.cgi;h=f3a4a7e76f11921aaa61c96a893a54b734fa0cd8;hb=1e266b439c4550432abc1c20512f6edf2786c88e;hp=f8b068387da4fbc9010249cda2dde2d31a46573e;hpb=3b182fa1fbdc7a9401fd5368010f98bb3025c034;p=vpaste diff --git a/index.cgi b/index.cgi index f8b0683..f3a4a7e 100755 --- a/index.cgi +++ b/index.cgi @@ -1,228 +1,357 @@ #!/bin/bash -# Copyright (C) 2009 Andy Spencer -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# Copyright (C) 2009-2012 Andy Spencer +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. # Remove url codings from stdin function get_modeline { - modeline=$( - echo "$QUERY_STRING" | - sed -e 's/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g; s/[,&]/ /g' | - xargs echo -e - ) - echo "vim: $modeline" + echo "$QUERY_STRING" | + sed -e 's/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g; s/[,&?]/ /g' | + xargs echo -e +} +function get_param { + get_modeline | awk -v "key=$1" 'BEGIN{RS=" "; FS="="}; $1 ~ key {print $2}' } # Extract an uploaded file from standard input -# $1 is the boundary delimiter for the file +# $1 is the name of the input to extract function cut_file { - awk -v "bnd=$1" '{ - if ($0 == "--"bnd"\r") { st=1; } - if ($0 == "--"bnd"--\r") { st=0; } - if (st == 2) { print $0; } - if ($0 == "\r" && st == 1) { st=2; } - }' | head -c -2 | head -c $((128*1024)) - # Remove trailing ^M's that come with CGI - # Limit size to 128K + bnd="${CONTENT_TYPE/*boundary\=/}" + awk -v "want=$1" -v "bnd=$bnd" ' + BEGIN { RS="\r\n" } + + # reset based on boundaries + $0 == "--"bnd"" { st=1; next; } + $0 == "--"bnd"--" { st=0; next; } + $0 == "--"bnd"--\r" { st=0; next; } + + # search for wanted file + st == 1 && $0 ~ "^Content-Disposition:.* name=\""want"\"" { st=2; next; } + st == 1 && $0 == "" { st=9; next; } + + # wait for newline, then start printing + st == 2 && $0 == "" { st=3; next; } + st == 3 { print $0 } + ' | head -c $((128*1024)) # Limit size to 128K } # Print out a generic header function header { echo "Content-Type: $1; charset=UTF-8" - echo + if [[ "$HTTP_ACCEPT_ENCODING" == *'gzip'* ]]; then + echo "Content-Encoding: gzip" + echo + exec 1> >(gzip) + else + echo + fi +} + +# Print plain message and exit +function message { + while [ "$1" == '-h' ]; do + shift; echo "$1"; shift + done + header text/plain + echo "$*" + exit } -# Format a file for viewing +# List previous pastes +function do_cmd { + header text/plain + case "$1" in + head) + awk ' + BEGIN { rows=4; cols=60; } + FNR==1 { gsub(/.*\//, "", FILENAME); + print FILENAME + print "-----" } + FNR==1,/^$/ { next } + /\S/ { i++; printf "%."cols"s\n", $0 } + i>=rows { i=0; print ""; nextfile } + ' $(ls -t db/*) + ;; + ls) + ls -t db | column + ;; + esac +} + +# Format a file for viewing function do_print { if [ -f "./$1" ]; then input="$1" elif [ -f "db/$1" ]; then input="db/$1" - trim='1d' # sed command to remove cruft + trim='1,/^$/d' # sed command to remove cruft else - echo "Status: 404 Not Found" - header text/plain - echo "File '$1' not found" - return + message -h 'Status: 404 Not Found' \ + "File '$1' not found" fi - - if [[ "$REQUEST_URI" == *'?'* ]]; then - # Create a temp file with the provided modeline - output="$(mktemp)" - tmp="$(mktemp)" - sed "1a$(get_modeline)" "$input" > "$tmp" - - # - I have some plugins in ~/.vim - # - Run ex in a pty to trick it into thinking that it - # has a real terminal, note that we also have to set - # term=xterm-256color in vimrc - HOME=/home/andy \ - /home/andy/bin/pty ex -nXZ -i NONE -u vimrc \ - '+set bexpr= fde= fdt= fex= inde= inex= key= pa= pexpr' \ - '+set iconstring= ruf= stl= tal=' \ - "+set titlestring=$1\ -\ vpaste.net" \ - '+set noml' \ - '+2d|'$trim \ - '+%s/\r//g' \ - '+TOhtml' \ - "+sav! $output" \ - '+qall!' \ - "$tmp" /dev/null 2>&1 - - header text/html - cat "$output" - rm "$tmp" "$output" - else + # Check for raw paste + if [[ "$QUERY_STRING" == 'raw'* || + "$REQUEST_URI" != *'?'* && + ( "$input" != 'db/'* || + "$HTTP_ACCEPT" != *'html'* ) ]]; then header text/plain sed "$trim" "$input" + exit fi + + # Create a temp file with the provided modeline + output="$(mktemp)" + tmp="$(mktemp)" + sed "\$avim: $(get_modeline)" "$input" > "$tmp" + + # - I have some plugins in ~/.vim + # - Run ex in screen to trick it into thinking that it + # has a real terminal, note that we also have to set + # term=xterm-256color in vimrc + HOME=/home/andy \ + screen -D -m ex -nXZ -i NONE -u vimrc \ + '+sil! set fde= fdt= fex= inde= inex= key= pa= pexpr=' \ + '+sil! set iconstring= ruf= stl= tal=' \ + "+sil! set titlestring=$1\ -\ vpaste.net" \ + '+sil! set noml' \ + '+sil! $d|'$trim \ + '+sil! %s/\r//g' \ + '+sil! TOhtml' \ + "+sav! $output" \ + '+qall!' \ + "$tmp" + + header text/html + cat "$output" + rm "$tmp" "$output" } # Upload handler function do_upload { - text=$(cut_file "$1") - if [ -z "$text" ]; then - header text/plain - echo "No text pasted" - exit - fi + body=$(cat -) + spam=$(echo -n "$body" | cut_file "ignoreme") + text=$(echo -n "$body" | cut_file "(text|x)") + [ ! -z "$spam" ] && message "Spam check.." + [ -z "$text" ] && message "No text pasted" + + # Format and save message output="$(mktemp db/XXXXX)" - uri="$url$(basename "$output")${QUERY_STRING:+"?"}" - (get_modeline; echo "$text") > "$output" - echo "Status: 302 Found" - echo "Location: $uri" - header text/plain - echo "$uri" + cat >"$output" <<-EOF + vim: $(get_modeline) + Date: $(date -R) + From: $REMOTE_ADDR + + $text + EOF + + # Redirect user + uri="$url$(basename "$output")" + message -h 'Status: 302 Found' \ + -h "Location: $uri" \ + "$uri" } # Default index page function do_help { -filetypes=$( - ls /usr/share/vim/vim*/syntax/ /home/andy/.vim/syntax/ | - sed -n '/^\(syntax\|manual\|synload\|2html\|colortest\|hitest\).vim$/d; s/.vim$//p' | - sort | uniq -) -uploads=$(ls -t db | head -n 5) - -header text/html -cat - < - - - vpaste.net - Vim based pastebin - - - - - - -
-
- - - -
-
- -

NAME

-

vpaste: Vim based pastebin

- -

SYNOPSIS

-
-
 vpaste file [option=value,..]
-
 <command> | vpaste [option=value,..]
-
-
 <command> | curl -F 'x=<-' $url[?option=value,..]
-
-
 :map vp :exec "w !vpaste ft=".&ft<CR>
-
 :vmap vp <ESC>:exec "'<,'>w !vpaste ft=".&ft<CR>
-
- -

DESCRIPTION

-

Add ?[option[=value],..] to make your text a rainbow.

-

Options specified when uploading are used as defaults.

- -

OPTIONS

-
-
ft, filetype={filetype}
-
A filetype to use for highlighting, see above menu for supported types
-
bg, background={light|dark}
-
Background color to use for the page
-
et, expandtab
-
Expand tabs to spaces
-
ts, tabstop=[N]
-
Number of spaces to use for tabs when et is set
-
...
-
See :help modeline for more information
-
- -

BUGS

- - -

SOURCE

- - -

LATEST UPLOADS

- - - -EOF + filetypes=$( + ls /usr/share/vim/vim*/syntax/ /home/andy/.vim/syntax/ | + sed -n '/^\(syntax\|manual\|synload\|2html\|colortest\|hitest\).vim$/d; s/.vim$//p' | + sort | uniq + ) + uploads=$(ls -t db | head -n 5) + filetype=$(get_param '^(ft|filet(y(pe?)?)?)$') + vpaste='vpaste' + + header text/html + cat <<-EOF + + + + vpaste.net - Vim based pastebin + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+ +
+

Pasting

+
+
From a shell
+
$vpaste file [option=value,..]
+
<command> | $vpaste [option=value,..]
+ +
From Vim
+
:map vp :exec "w !vpaste ft=".&ft<CR>
+
:vmap vp <ESC>:exec "'<,'>w !vpaste ft=".&ft<CR>
+ +
With curl
+
<command> | curl -F 'text=<-' $url[?option=value,..]
+
+ +

Options

+

Add ?option[=value],.. to make your text a rainbow.

+

Options specified when uploading are saved as defaults.

+ +
+
bg, background={light|dark}
+
Background color to use for the page
+
et, expandtab
+
Expand tabs to spaces
+
fdm, foldmethod=(syntax|indent)
+
Turn on dynamic code folding
+
ft, filetype={filetype}
+
A filetype to use for highlighting, see above menu for supported types
+
nu, number
+
Add line numbers
+
ts, tabstop=[N]
+
Number of spaces to use for tabs when et is set
+
...
+
See :help modeline for more information
+
+
+ +
+

License

+

Copyright © 2009-2012 + Andy Spencer <andy753421@gmail.com>

+

See individual files for licenses

+ +

Source code

+ + +

Bugs

+ +
+ +
+

Recent Uploads

+ +

list all

+

sample all

+
+ + + EOF } # Main +PATH=/bin:/usr/bin url="http://$HTTP_HOST${REQUEST_URI/\?*}" pathinfo="${REQUEST_URI/*\/}" pathinfo="${pathinfo/\?*}" -if [ "$pathinfo" ]; then +if [ "$pathinfo" = ls ]; then + do_cmd ls +elif [ "$pathinfo" = head ]; then + do_cmd head +elif [ "$pathinfo" ]; then do_print "$pathinfo" elif [ "$CONTENT_TYPE" ]; then - do_upload "${CONTENT_TYPE/*boundary\=/}" + do_upload else do_help fi