#!/usr/bin/head -5
# -*- mode: shell-script -*-
# CGI Library v2 for Shell Script
# Use this by source'ing.
# . ./cgilib2-sh

PATH=/usr/local/sqlite3/bin:$PATH
_db=${DB:-db/cgi.sq3}		# 変数DBで変更可能にしておく
query() {
  sqlite3 -cmd '.timeout 3000' -cmd 'PRAGMA foreign_keys=on' $_db "$@"
}
escape() {			   # HTMLエスケープ
  printf "%s" "$@" |
      sed -e '; s/\&/\&amp;/g' -e 's/"/\&quot;/g' -e "s/'/\&apos;/g" \
	  -e "s/</\&lt;/g; s/>/\&gt;/g"
}
_tag=`date +%s`.$$		# CGIパラメータのタグをEPOCH秒とPID値から生成
_exp='+1 minutes'      		# 1時間後にexpire
tmpd=`TMPDIR=${TMPDIR:-tmp} mktemp -d -t cgi.$_tag.XXXXXX` || exit 1
cleandir() {
  rm -r $tmpd
}
trap cleandir EXIT INT TERM HUP

hexize() {
  #hexdump -ve '1/1 "%.2x"'
  perl -ne 'print unpack("H*", $_);'
}
unhexize() {
  perl -n -e 's/([0-9a-f]{2})/print chr hex $1/gie'
}
pdecode() {
  tr '%+' '= '| nkf -Ww -mQ
}
storeparam() (
  IFS='&'		# サブシェル化された関数なのでIFSを保存せず変更
  { cat<<EOF		# この出力は { } グループを出たあとの query() に渡る
BEGIN;
CREATE TABLE IF NOT EXISTS tags(id text PRIMARY KEY, expire TEXT);
CREATE TABLE IF NOT EXISTS cgipars(
  tag, name text, val text, filename,
  FOREIGN KEY(tag) REFERENCES tags(id) ON DELETE CASCADE
);
INSERT INTO tags VALUES('$_tag', datetime('now', '$_exp', 'localtime'));
DELETE FROM tags WHERE expire < datetime('now', 'localtime');
EOF
    for unit in $1; do		# & で文字列を分割して unit に代入して繰り返す
      n=${unit%%=*}		# 入力名=値 の「入力名」を取り出す
      v=${unit#*=}		# 入力名=値 の「値」を取り出す
      # SQLでは文字列中のシングルクォート(')は2つ重ねてエスケープ(sed部分)
      n=`echo "$n" | pdecode | sed -e "s/'/''/g"`
      v=`echo "$v" | pdecode | sed -e "s/'/''/g"`
      case "$n" in
	*:filename)
	  n=${n%:filename}
	  cat<<EOF		# hexize関数でエンコードしたものを挿入
REPLACE INTO cgipars VALUES('$_tag', '$n', X'`hexize < $tmpd/$v`', '$v');
EOF
	  ;;
	?*)			# :filenameがなければ name, val のみの挿入
	  echo "REPLACE INTO cgipars VALUES('$_tag', '$n', '$v', NULL);"
	  ;;
      esac
    done
    echo "COMMIT;"
  } | query
)
getpar() {			# 指定したパラメータの値を改行区切りで返す
  query<<EOF
SELECT val FROM cgipars WHERE name = '$1' AND tag='$_tag';
EOF
}
contenttype() {
  echo "Content-type: ${1:-text/html; charset=utf-8}"
  contenttype() {}		# 一度出力したら不要になる
}
htmlhead() {			# Content-type から HTML body要素開始まで
  contenttype; echo
  cat<<EOF			# $1=タイトル
<!DOCTYPE html>
<html lang="ja"><head><title>$1</title>
<link type="text/css" rel="stylesheet" href="mycgi.css"></head>
<body${bodyclass:+ class="$bodyclass"}>
<h1>$1</h1>
EOF
}

case "$REQUEST_METHOD" in
  get|GET)			# GETの場合は環境変数から取得
    par="$QUERY_STRING" ;;
  post|POST)			# POSTなら $CONTENT_LENGTH だけ標準入力を読む
    stream=$tmpd/stream
    head -c $CONTENT_LENGTH > $stream
    case $CONTENT_TYPE in
      *boundary=*)
	boundary=${CONTENT_TYPE#*boundary=}
	par=`./mpsplit.pl "$boundary" $tmpd < $stream` ;;
      *)
	par=`cat $stream` ;;
    esac
    ;;
esac

storeparam "$par"		# 受け取ったパラメータをDBに格納
