#!/bin/sh exec 2>>error.log . shcgi/cgilite.sh mkdir -p users # printf 'POST: %s\n' "$cgilite_post" >>debug # printf 'action: %s\n' "$(GET action)" >>debug wget="$(which wget)" wget(){ "$wget" -T 5 -t 1 -q -U '' $@; } checkid(){ grep -m 1 -xE '[0-9a-zA-Z:_]{12}'; } genid(){ # generate random ID head -c9 /dev/urandom \ | uuencode -m - \ | sed -n '2{y;+/;:_;;p}' } timeid(){ # generate time based ID d=$(date +%s) { printf $( while [ "$d" -gt 0 ]; do printf \\%o $((d % 256)) d=$((d / 256)) done ) | tac head -c5 /dev/urandom } \ | uuencode -m - \ | sed -n '2{y;+/;:_;;p}' } getFavicon(){ url="$1" bid="$2" prot=${url%%://*} domain="${url#*://}" domain="${domain%%/*}" ubase="${prot}://${domain}" file="${BDB}/favicons/${bid}.ico" mkdir -p "${BDB}/favicons/" && chmod a+rx "${BDB}/favicons/" favinfo="$( wget -O- "$url" \ | head -c4096 \ | sed -rn \ 's;^.*(<[Ll][Ii][Nn][Kk]( [^>]*)? [Rr][Re][Ll]='\''([Ss][Hh][Oo][Rr][Tt][Cc][Uu][Tt] )?[Ii][Cc][Oo][Nn]'\''[^>]*>).*$;\1;; s;^.*(<[Ll][Ii][Nn][Kk]( [^>]*)? [Rr][Re][Ll]="([Ss][Hh][Oo][Rr][Tt][Cc][Uu][Tt] )?[Ii][Cc][Oo][Nn]"[^>]*>).*$;\1;; tX; b; :X; s;^.*<([^>]+) [Hh][Rr][Ee][Ff]="([^"]+)".*$:\2;; s;^.*<([^>]+) [Hh][Rr][Ee][Ff]='\''([^'\'']+)'\''.*$:\2;; tY; b; :Y; p ' )" # printf 'Shortcut icon for %s is %s\n' "$url" "$favinfo" >>debug [ -z "$favinfo" ] && favinfo="${ubase}/favicon.ico" case "$favinfo" in http://*|https://*|//*) wget -O "$file" "$favinfo" ;; /*) wget -O "$file" "${ubase}/${favinfo}" ;; *) wget -O "$file" "${url%/*}/${favinfo}" ;; esac [ -f "${file}.1" ] && mv "${file}.1" "$file" chmod a+r "$file" } list_folders(){ head -qn1 "${BDB}"/????????????.bm \ | sort -nk3 \ | cut -f1,2 } order_files(){ n=1000 list_folders \ | while read fid nan; do file="${BDB}/${fid}.bm" sed -ri "1s;^(([^\t]+\t){2})[^\t]+(.*)$;\1${n}\3;;" "$file" n=$((n + 1000)) done } COKID="$(COOKIE id |checkid)" QRYID="$(GET id |checkid)" BDB="users/${COKID}" if [ -n "$QRYID" ]; then printf 'Status: 303 See Other\r\n' printf 'Location: %s\r\n' "${SCRIPT_NAME}?${QUERY_STRING#id=????????????}" SET_COOKIE +8640000 "id=${QRYID}" printf '\r\n' exit 0 elif [ -z "$COKID" -a -z "$QRYID" ]; then printf 'Content-Type: text/html; charset=utf-8\r\n\r\n' cat <<-EOF Bookman - New Collection

You have not yet set up a collection on this server.

Click here to start a new collection. EOF exit 0 elif ! [ -d "${BDB}" ]; then printf 'Status: 404 Not Found\r\n' printf 'Content-Type: text/html; charset=utf-8\r\n\r\n' cat <<-EOF Bookman - 404

The collection you requested does not exist on this server.

Click here to start a new collection. EOF exit 0 fi case "$(GET action)" in newid) NEWID="$(genid)" { git init "users/${NEWID}" || mkdir -p "users/${NEWID}"; } >&- printf 'Status: 303 See Other\r\n' printf 'Location: %s\r\n' "${SCRIPT_NAME}?id=${NEWID}" SET_COOKIE +8640000 "id=${NEWID}" printf '\r\n' exit 0 ;; newfolder) name="$(POST name |head -n1)" fid="$(timeid)" order="$( head -qn1 "${BDB}"/????????????.bm \ | cut -f3 \ | sort -n \ | tail -n1 \ || printf 1 )" order="$(((order + 1000) / 1000 * 1000))" if [ -n "$name" -a -d "${BDB}" ]; then printf '%s\t%s\t%s\n' "$fid" "$(HTML "$name")" "$order" >"${BDB}/${fid}.bm" git -C "${BDB}" add "${fid}.bm" >&- git -C "${BDB}" commit -m "New bookmark folder: ${name} (${fid})" -- "${fid}.bm" >&- fi REDIRECT "${SCRIPT_NAME}#${fid}" ;; modfolder) name="$(POST name |head -n1)" fid="$(POST fid | checkid)" file="${BDB}/${fid}.bm" if [ "$(POST control)" = confirm -a -n "$name" -a -f "$file" ]; then sed -ri "1s'^(${fid}\t)[^\t]+(\t.+)$'\1${name}\2';" "$file" git -C "${BDB}" add "${fid}.bm" >&- git -C "${BDB}" commit -m "Renamed folder ${fid} to '${name}'" -- "${fid}.bm" >&- fi REDIRECT "${SCRIPT_NAME}#${fid}" ;; delfolder) fid="$(POST fid | checkid)" target="$(POST target | checkid)" file="${BDB}/${fid}.bm" tfile="${BDB}/${target}.bm" if [ "$(POST control)" = confirm -a -f "$file" ]; then if [ "$target" = "____________" ]; then rm -f "$file" "${file%.bm}.cache" >&- git -C "${BDB}" commit -m "Deleted folder ${fid}" -- "${fid}.bm" >&- elif tail -n+2 "$file" >>"$tfile"; then rm -f "$file" "${file%.bm}.cache" >&- git -C "${BDB}" commit -m "Deleted folder ${fid}" -- "${fid}.bm" "${target}.bm" >&- fi fi REDIRECT "${SCRIPT_NAME}#${target}" ;; movefolder) fid="$(POST fid | checkid)" target="$(POST target | checkid)" file="${BDB}/${fid}.bm" tfile="${BDB}/${target}.bm" if [ "$target" = "____________" -a -f "$file" -a "$(POST control)" = confirm ]; then read nan1 nan2 last nan3 <"${BDB}/$(list_folders |tail -n1 |cut -f1).bm" sed -ri "1s;^(([^\t]+\t){2})[^\t]+(.*)$;\1$((${last:-0} + 1000))\3;;" "$file" elif [ -f "$tfile" -a -f "$file" -a "$(POST control)" = confirm ]; then read nan1 nan2 tid nan3 <"$tfile" sed -ri "1s;^(([^\t]+\t){2})[^\t]+(.*)$;\1$((${tid:-1} -1))\2;;" "$file" order_files fi git -C "${BDB}" commit -a -m "Modified folder order (moved ${fid})" >&- REDIRECT "${SCRIPT_NAME}#${fid}" ;; newbookmark) fid="$(POST fid | checkid)" name="$(POST name |head -n1)" url="$(POST url |head -n1)" file="${BDB}/${fid}.bm" bid="$(timeid)" ctl="$(POST control)" [ "$url" = "${url#*://}" ] && url="http://$url" if [ -n "$name" -a -n "$url" -a -f "${file}" -a "$ctl" = "confirm" ]; then printf '%s\t%s\t%s\n' "$bid" "$(HTML "$name")" "$url" >>"${file}" git -C "${BDB}" commit -m "New Bookmark: ${name} in ${fid}" -- "${fid}.bm" >&- getFavicon "$url" "$bid" REDIRECT "${SCRIPT_NAME}#${fid}" elif [ "$ctl" = "confirm" ]; then REDIRECT "${SCRIPT_NAME}?newbm=${fid}&nbmurl=${url}&nbmname=${name}" else REDIRECT "${SCRIPT_NAME}#${fid}" fi ;; modbookmark) bid="$(POST bid | checkid)" name="$(POST name |head -n1)" url="$(POST url |head -n1)" file="$(grep -lm1 "^${bid}" "${BDB}"/????????????.bm |head -n1)" if [ -n "$name" -a -n "$url" -a "$(POST control)" = confirm -a -w "$file" ]; then sed -rni "/^${bid}\t/!p; /^${bid}\t/i${bid}\t$(HTML "$name")\t${url}" "$file" git -C "${BDB}" commit -m "Modified Bookmark: ${name} (${bid}) in ${file##*/}" -- "${file##*/}" >&- fi getFavicon "$url" "$bid" REDIRECT "${SCRIPT_NAME}#${fid}" ;; movebookmark) bid="$(POST bid | checkid)" fid="$(POST target | checkid)" sfile="$(grep -lm1 "^${bid}" "${BDB}"/????????????.bm |head -n1)" tfile="${BDB}/${fid}.bm" if [ "$(POST control)" = confirm -a -n "$bid" -a -w "$sfile" -a -w "$tfile" ]; then grep -m1 "^${bid}" "$sfile" >>"$tfile" \ && sed -ri "0,/^${bid}/{/^${bid}/d;}" "$sfile" git -C "${BDB}" commit -m "Moved Bookmark ${bid} from ${sfile##*/} to ${tfile##*/}" \ -- "${sfile##*/}" "${tfile##*/}" >&- fi REDIRECT "${SCRIPT_NAME}#${fid}" ;; bmup) fid="$(GET fid |checkid)" bid="$(GET bid |checkid)" file="${BDB}/${fid}.bm" if [ -n "$bid" -a -n "$fid" ] && grep -q "^${bid}" "$file"; then sed -ri ":X;\$bY;N;bX;:Y; s;(\n[^\n]+)(\n${bid}\t[^\n]+);\2\1;;" "$file" git -C "${BDB}" commit -m "Modified bookmark order in ${fid} (raised ${bid})" -- "${fid}.bm" >&- fi REDIRECT "${SCRIPT_NAME}#${fid}" ;; bmdn) fid="$(GET fid |checkid)" bid="$(GET bid |checkid)" file="${BDB}/${fid}.bm" if [ -n "$bid" -a -n "$fid" ] && grep -q "^${bid}" "$file"; then sed -ri ":X;\$bY;N;bX;:Y; s;(\n${bid}\t[^\n]+)(\n[^\n]+);\2\1;;" "$file" git -C "${BDB}" commit -m "Modified bookmark order in ${fid} (lowered ${bid})" -- "${fid}.bm" >&- fi REDIRECT "${SCRIPT_NAME}#${fid}" ;; query) fid="$(POST fid |checkid)" bid="$(POST bid |checkid)" file="${BDB}/${fid}.bm" query="$(URL "$(POST query)")" url="$(grep -m1 "^${bid}" "$file" |cut -f3-)" urlpfx="${url%\{@\}*}" urlsfx="${url#*\{@\}}" REDIRECT "${urlpfx}${query}${urlsfx}" ;; esac bookmarkgen(){ fid="$(GET newbm |checkid)" name="$(GET nbmname)" url="$(GET nbmurl)" file="${BDB}/${fid}.bm" if [ -z "$name" -a -n "$url" ]; then name="$(wget -O- "$url" \ | head -c4096 \ | sed -rn ':X;$bY;N;bX;:Y; s;^.*]*>([^<]+)<.*$;\1;p;' )" fi if [ -n "$fid" -o -n "$name" -o -n "$url" ]; then [ "$url" = "${url#*://}" ] && url="http://$url" cat <<-EOF

New Bookmark

EOF fi } bookmarkmod(){ bmod="$(GET bmodify |checkid)" bmove="$(GET bmove |checkid)" if [ -n "$bmod" ]; then file="$(grep -lm1 "^${bmod}" "${BDB}/"????????????.bm |head -n1)" read bid name url <<-EOF $(grep -m1 "^${bmod}" "$file") EOF cat <<-EOF

Modify: ${name}

Move
EOF elif [ -n "$bmove" ]; then file="$(grep -lm1 "^${bmove}" "${BDB}/"????????????.bm |head -n1)" read bid name url <<-EOF $(grep -m1 "^${bmove}" "$file") EOF cat <<-EOF

Move: ${name}

Modify
EOF fi } show_bookmarks(){ fid="$1" bmodify="$(GET bmodify |checkid)" tail -n+2 "${BDB}/${fid}.bm" \ | while read bid name url; do if [ "${url%\{@\}*}" = "${url}" ]; then cat <<-EOF
Modify @${name} Move up Move down
EOF else cat <<-EOF
Modify ${name} Move up Move down
EOF fi done } foldermod(){ fmodify="$(GET fmodify |checkid )" fdelete="$(GET fdelete |checkid )" fmove="$(GET fmove |checkid )" if [ -n "$fmodify" ]; then read fid fname order <"${BDB}/${fmodify}.bm" cat <<-EOF

Rename Folder: ${fname}

Delete Move
EOF elif [ -n "$fdelete" ]; then read fid fname order <"${BDB}/${fdelete}.bm" cat <<-EOF

Delete Folder: ${fname}

Rename Move
EOF elif [ -n "$fmove" ]; then read fid fname order <"${BDB}/${fmove}.bm" cat <<-EOF

Move Folder: ${fname}

Rename Delete
EOF fi } show_folders(){ list_folders \ | while read fid fname order; do file="${BDB}/${fid}.bm" cache="${BDB}/${fid}.cache" if [ "${cache}" -nt "${file}" -a "${cache}" -nt "$0" ]; then cat "$cache" else tee "$cache" <<-EOF

${fname}

Modify folder "${fname}" $(show_bookmarks "$fid") New Bookmark
EOF fi done } SET_COOKIE +8640000 "id=${COKID}" # Refresh Cookie printf 'Content-Type: text/html; charset=utf-8\r\n\r\n' cat < Bookman - Your Collection $(foldermod) $(bookmarkmod) $(bookmarkgen) $(show_folders)
EOF #set filetype=sh