7 # printf 'POST: %s\n' "$cgilite_post" >>debug
8 # printf 'action: %s\n' "$(GET action)" >>debug
11 wget(){ "$wget" -T 5 -t 1 -q -U '' $@; }
12 checkid(){ grep -m 1 -xE '[0-9a-zA-Z:_]{12}'; }
16 head -c9 /dev/urandom \
18 | sed -n '2{y;+/;:_;;p}'
22 # generate time based ID
25 while [ "$d" -gt 0 ]; do
26 printf \\%o $((d % 256))
33 | sed -n '2{y;+/;:_;;p}'
41 domain="${domain%%/*}"
42 ubase="${prot}://${domain}"
43 file="${BDB}/favicons/${bid}.ico"
45 mkdir -p "${BDB}/favicons/" && chmod a+rx "${BDB}/favicons/"
51 's;^.*(<[Ll][Ii][Nn][Kk]( [^>]*)? [Rr][Re][Ll]='\''([Ss][Hh][Oo][Rr][Tt][Cc][Uu][Tt] )?[Ii][Cc][Oo][Nn]'\''[^>]*>).*$;\1;;
52 s;^.*(<[Ll][Ii][Nn][Kk]( [^>]*)? [Rr][Re][Ll]="([Ss][Hh][Oo][Rr][Tt][Cc][Uu][Tt] )?[Ii][Cc][Oo][Nn]"[^>]*>).*$;\1;;
54 s;^.*<([^>]+) [Hh][Rr][Ee][Ff]="([^"]+)".*$:\2;;
55 s;^.*<([^>]+) [Hh][Rr][Ee][Ff]='\''([^'\'']+)'\''.*$:\2;;
60 # printf 'Shortcut icon for %s is %s\n' "$url" "$favinfo" >>debug
61 [ -z "$favinfo" ] && favinfo="${ubase}/favicon.ico"
63 http://*|https://*|//*) wget -O "$file" "$favinfo"
65 /*) wget -O "$file" "${ubase}/${favinfo}"
67 *) wget -O "$file" "${url%/*}/${favinfo}"
70 [ -f "${file}.1" ] && mv "${file}.1" "$file"
75 head -qn1 "${BDB}"/????????????.bm \
83 | while read fid nan; do
84 file="${BDB}/${fid}.bm"
85 sed -ri "1s;^(([^\t]+\t){2})[^\t]+(.*)$;\1${n}\3;;" "$file"
90 COKID="$(COOKIE id |checkid)"
91 QRYID="$(GET id |checkid)"
94 if [ -n "$QRYID" ]; then
95 printf '%s 303 See Other\r\n' "$SERVER_PROTOCOL"
96 printf 'Location: %s\r\n' "${SCRIPT_NAME}?${QUERY_STRING#id=*&}"
97 SET_COOKIE +8640000 "id=${QRYID}"
100 elif [ -z "$COKID" -a -z "$QRYID" ]; then
101 printf 'Content-Type: text/html; charset=utf-8\r\n\r\n'
106 <title>Bookman - New Collection</title>
107 </head><body id="newcollection">
108 <h1>You have not yet set up a collection on this server.</h1>
109 Click <a href="${SCRIPT_NAME}?action=newid">here</a> to start a new collection.
113 elif ! [ -d "${BDB}" ]; then
114 printf '%s 404 Not Found\r\n' "$SERVER_PROTOCOL"
115 printf 'Content-Type: text/html; charset=utf-8\r\n\r\n'
120 <title>Bookman - 404</title>
121 </head><body id="missingcollection">
122 <h1>The collection you requested does not exist on this server.</h1>
123 Click <a href="${SCRIPT_NAME}?action=newid">here</a> to start a new collection.
129 case "$(GET action)" in
133 { git init "users/${NEWID}" || mkdir -p "users/${NEWID}"; } >&-
135 printf '%s 303 See Other\r\n' "$SERVER_PROTOCOL"
136 printf 'Location: %s\r\n' "${SCRIPT_NAME}?id=${NEWID}"
137 SET_COOKIE +8640000 "id=${NEWID}"
142 name="$(POST name |head -n1)"
145 head -qn1 "${BDB}"/????????????.bm \
151 order="$(((order + 1000) / 1000 * 1000))"
152 if [ -n "$name" -a -d "${BDB}" ]; then
153 printf '%s\t%s\t%s\n' "$fid" "$(HTML "$name")" "$order" >"${BDB}/${fid}.bm"
154 git -C "${BDB}" add "${fid}.bm" >&-
155 git -C "${BDB}" commit -m "New bookmark folder: ${name} (${fid})" -- "${fid}.bm" >&-
157 REDIRECT "${SCRIPT_NAME}#${fid}"
160 name="$(POST name |head -n1)"
161 fid="$(POST fid | checkid)"
162 file="${BDB}/${fid}.bm"
163 if [ "$(POST control)" = confirm -a -n "$name" -a -f "$file" ]; then
164 sed -ri "1s'^(${fid}\t)[^\t]+(\t.+)$'\1${name}\2';" "$file"
165 git -C "${BDB}" add "${fid}.bm" >&-
166 git -C "${BDB}" commit -m "Renamed folder ${fid} to '${name}'" -- "${fid}.bm" >&-
168 REDIRECT "${SCRIPT_NAME}#${fid}"
171 fid="$(POST fid | checkid)"
172 target="$(POST target | checkid)"
173 file="${BDB}/${fid}.bm"
174 tfile="${BDB}/${target}.bm"
175 if [ "$(POST control)" = confirm -a -f "$file" ]; then
176 if [ "$target" = "____________" ] || tail -n+2 "$file" >>"$tfile"; then
178 git -C "${BDB}" commit -m "Deleted folder ${fid}" -- "${fid}.bm" "${target}.bm" >&-
181 REDIRECT "${SCRIPT_NAME}#${target}"
184 fid="$(POST fid | checkid)"
185 target="$(POST target | checkid)"
186 file="${BDB}/${fid}.bm"
187 tfile="${BDB}/${target}.bm"
188 if [ "$target" = "____________" -a -f "$file" -a "$(POST control)" = confirm ]; then
189 read nan1 nan2 last nan3 <"${BDB}/$(list_folders |tail -n1 |cut -f1).bm"
190 sed -ri "1s;^(([^\t]+\t){2})[^\t]+(.*)$;\1$((${last:-0} + 1000))\3;;" "$file"
191 elif [ -f "$tfile" -a -f "$file" -a "$(POST control)" = confirm ]; then
192 read nan1 nan2 tid nan3 <"$tfile"
193 sed -ri "1s;^(([^\t]+\t){2})[^\t]+(.*)$;\1$((${tid:-1} -1))\2;;" "$file"
196 git -C "${BDB}" commit -a -m "Modified folder order (moved ${fid})" >&-
197 REDIRECT "${SCRIPT_NAME}#${fid}"
200 fid="$(POST fid | checkid)"
201 name="$(POST name |head -n1)"
202 url="$(POST url |head -n1)"
203 file="${BDB}/${fid}.bm"
205 if [ -n "$name" -a -f "${file}" ]; then
206 printf '%s\t%s\t%s\n' "$bid" "$(HTML "$name")" "$url" >>"${file}"
207 git -C "${BDB}" commit -m "New Bookmark: ${name} in ${fid}" -- "${fid}.bm" >&-
209 getFavicon "$url" "$bid"
210 REDIRECT "${SCRIPT_NAME}#${fid}"
213 bid="$(POST bid | checkid)"
214 name="$(POST name |head -n1)"
215 url="$(POST url |head -n1)"
216 file="$(grep -lm1 "^${bid}" "${BDB}"/????????????.bm |head -n1)"
217 if [ -n "$name" -a -n "$url" -a "$(POST control)" = confirm -a -w "$file" ]; then
218 sed -rni "/^${bid}\t/!p; /^${bid}\t/i${bid}\t$(HTML "$name")\t${url}" "$file"
219 git -C "${BDB}" commit -m "Modified Bookmark: ${name} (${bid}) in ${file##*/}" -- "${file##*/}" >&-
221 getFavicon "$url" "$bid"
222 REDIRECT "${SCRIPT_NAME}#${fid}"
225 bid="$(POST bid | checkid)"
226 fid="$(POST target | checkid)"
227 sfile="$(grep -lm1 "^${bid}" "${BDB}"/????????????.bm |head -n1)"
228 tfile="${BDB}/${fid}.bm"
230 if [ "$(POST control)" = confirm -a -n "$bid" -a -w "$sfile" -a -w "$tfile" ]; then
231 grep -m1 "^${bid}" "$sfile" >>"$tfile" \
232 && sed -ri "0,/^${bid}/{/^${bid}/d;}" "$sfile"
233 git -C "${BDB}" commit -m "Moved Bookmark ${bid} from ${sfile##*/} to ${tfile##*/}" \
234 -- "${sfile##*/}" "${tfile##*/}" >&-
236 REDIRECT "${SCRIPT_NAME}#${fid}"
239 fid="$(GET fid |checkid)"
240 bid="$(GET bid |checkid)"
241 file="${BDB}/${fid}.bm"
243 if [ -n "$bid" -a -n "$fid" ] && grep -q "^${bid}" "$file"; then
244 sed -ri ":X;\$bY;N;bX;:Y; s;(\n[^\n]+)(\n${bid}\t[^\n]+);\2\1;;" "$file"
245 git -C "${BDB}" commit -m "Modified bookmark order in ${fid} (raised ${bid})" -- "${fid}.bm" >&-
247 REDIRECT "${SCRIPT_NAME}#${fid}"
250 fid="$(GET fid |checkid)"
251 bid="$(GET bid |checkid)"
252 file="${BDB}/${fid}.bm"
254 if [ -n "$bid" -a -n "$fid" ] && grep -q "^${bid}" "$file"; then
255 sed -ri ":X;\$bY;N;bX;:Y; s;(\n${bid}\t[^\n]+)(\n[^\n]+);\2\1;;" "$file"
256 git -C "${BDB}" commit -m "Modified bookmark order in ${fid} (lowered ${bid})" -- "${fid}.bm" >&-
258 REDIRECT "${SCRIPT_NAME}#${fid}"
261 fid="$(POST fid |checkid)"
262 bid="$(POST bid |checkid)"
263 file="${BDB}/${fid}.bm"
264 query="$(URL "$(POST query)")"
267 url="$(grep -m1 "^${bid}" "$file" |cut -f3-)"
268 urlpfx="${url%\{@\}*}"
269 urlsfx="${url#*\{@\}}"
271 REDIRECT "${urlpfx}${query}${urlsfx}"
276 bmod="$(GET bmodify |checkid)"
277 bmove="$(GET bmove |checkid)"
279 if [ -n "$bmod" ]; then
280 file="$(grep -lm1 "^${bmod}" "${BDB}/"????????????.bm |head -n1)"
281 read bid name url <<-EOF
282 $(grep -m1 "^${bmod}" "$file")
285 <form class="modbookmark" method="POST" action="${SCRIPT_NAME}?action=modbookmark">
286 <input type="hidden" name="bid" value="${bid}" />
287 <h1>Modify: ${name}</h1>
288 <label class="tab">Modify</label>
289 <a class="tab" href="${SCRIPT_NAME}?bmove=${bid}">Move</a>
291 <input type="text" name="name" value="${name}")" placeholder="Name" />
293 <input type="text" name="url" value="$(HTML "${url}")")" placeholder="URL" />
294 <button type="submit" name="control" value="confirm">OK</button>
295 <button type="submit" name="control" value="cancel">Cancel</button>
298 elif [ -n "$bmove" ]; then
299 file="$(grep -lm1 "^${bmove}" "${BDB}/"????????????.bm |head -n1)"
300 read bid name url <<-EOF
301 $(grep -m1 "^${bmove}" "$file")
304 <form class="modbookmark" method="POST" action="${SCRIPT_NAME}?action=movebookmark">
305 <input type="hidden" name="bid" value="${bid}" />
306 <h1>Move: ${name}</h1>
307 <a class="tab" href="${SCRIPT_NAME}?bmodify=${bid}">Modify</a>
308 <label class="tab">Move</label>
309 <label>Move to Folder:</label>
310 <select name="target">
311 $(printf '<option value="%s">%s</option>' $(list_folders))
313 <button type="submit" name="control" value="confirm">OK</button>
314 <button type="submit" name="control" value="cancel">Cancel</button>
322 bmodify="$(GET bmodify |checkid)"
324 tail -n+2 "${BDB}/${fid}.bm" \
325 | while read bid name url; do
326 if [ "${url%\{@\}*}" = "${url}" ]; then
328 <div class="bookmark">
329 <a class="modify" href="${SCRIPT_NAME}?bmodify=${bid}">Modify</a>
330 <a class="link" target="_blank" href="$(HTML "${url}")")">
331 <img alt="@" src="${BDB}/favicons/${bid}.ico"/>${name}
333 <a class="bmove" href="${SCRIPT_NAME}?action=bmup&fid=${fid}&bid=${bid}">Move up</a>
334 <a class="bmove" href="${SCRIPT_NAME}?action=bmdn&fid=${fid}&bid=${bid}">Move down</a>
339 <form class="bookmark" target="_blank" method="POST" action="${SCRIPT_NAME}?action=query">
340 <a class="modify" href="${SCRIPT_NAME}?bmodify=${bid}">Modify</a>
341 <input type="hidden" name="fid" value="$fid" />
342 <input type="hidden" name="bid" value="$bid" />
343 <img alt="${name}" src="${BDB}/favicons/${bid}.ico"/>
344 <input name="query" placeholder="$name"/>
345 <a class="bmove" href="${SCRIPT_NAME}?action=bmup&fid=${fid}&bid=${bid}">Move up</a>
346 <a class="bmove" href="${SCRIPT_NAME}?action=bmdn&fid=${fid}&bid=${bid}">Move down</a>
354 fmodify="$(GET fmodify |checkid )"
355 fdelete="$(GET fdelete |checkid )"
356 fmove="$(GET fmove |checkid )"
358 if [ -n "$fmodify" ]; then
359 read fid fname order <"${BDB}/${fmodify}.bm"
361 <form class="modfolder rename" method="POST" action="${SCRIPT_NAME}?action=modfolder">
362 <h1>Rename Folder: ${fname}</h1>
363 <input type="hidden" name="fid" value="${fid}" />
364 <label class="tab">Rename</label>
366 href="${SCRIPT_NAME}?fdelete=${fid}">Delete</a>
368 href="${SCRIPT_NAME}?fmove=${fid}">Move</a>
369 <input type="text" name="name" value="${fname}" />
370 <button type="submit" name="control" value="confirm">OK</button>
371 <button type="submit" name="control" value="cancel">Cancel</button>
374 elif [ -n "$fdelete" ]; then
375 read fid fname order <"${BDB}/${fdelete}.bm"
377 <form class="modfolder delete" method="POST" action="${SCRIPT_NAME}?action=delfolder">
378 <h1>Delete Folder: ${fname}</h1>
379 <input type="hidden" name="fid" value="${fid}" />
380 <a class="tab" href="${SCRIPT_NAME}?fmodify=${fid}">Rename</a>
381 <label class="tab">Delete</label>
383 href="${SCRIPT_NAME}?fmove=${fid}">Move</a>
384 <label>Pass Bookmarks on to:</label>
385 <select name="target">
386 $(printf '<option value="%s">%s</option>' $(list_folders |grep -v "^${fid}"))
387 <option value="____________">(discard)</option>
389 <button type="submit" name="control" value="confirm">OK</button>
390 <button type="submit" name="control" value="cancel">Cancel</button>
393 elif [ -n "$fmove" ]; then
394 read fid fname order <"${BDB}/${fmove}.bm"
396 <form class="modfolder move" method="POST" action="${SCRIPT_NAME}?action=movefolder">
397 <h1>Move Folder: ${fname}</h1>
398 <input type="hidden" name="fid" value="${fid}" />
399 <a class="tab" href="${SCRIPT_NAME}?fmodify=${fid}">Rename</a>
400 <a class="tab" href="${SCRIPT_NAME}?fdelete=${fid}">Delete</a>
401 <label class="tab">Move</label>
402 <label>Move before folder:</label>
403 <select name="target">
404 $(printf '<option value="%s">%s</option>' $(list_folders |grep -v "^${fid}"))
405 <option value="____________">(last)</option>
407 <button type="submit" name="control" value="confirm">OK</button>
408 <button type="submit" name="control" value="cancel">Cancel</button>
416 | while read fid fname order; do
417 file="${BDB}/${fid}.bm"
418 cache="${BDB}/${fid}.cache"
419 if [ "${cache}" -nt "${file}" ]; then
423 <section class="folder" id="${fid}">
425 <a class="modify" href="${SCRIPT_NAME}?fmodify=${fid}">Modify folder "${fname}"</a>
426 $(show_bookmarks "$fid")
427 <form class="newbookmark" method="POST" action="${SCRIPT_NAME}?action=newbookmark">
428 <input type="hidden" name="fid" value="${fid}" />
429 <input type="text" name="name" value="" placeholder="Name" />
430 <input type="text" name="url" value="" placeholder="URL" />
431 <button type="submit">New Bookmark</button>
439 SET_COOKIE +8640000 "id=${COKID}" # Refresh Cookie
440 printf 'Content-Type: text/html; charset=utf-8\r\n\r\n'
445 <title>Bookman - Your Collection</title>
446 <link rel="stylesheet" type="text/css" href="bookmarks.css" />
447 </head><body id="collection">
451 <form class="newfolder" method="POST" action="${SCRIPT_NAME}?action=newfolder">
452 <input type="text" name="name" value="" placeholder="New Folder" />
453 <button type="submit">New</button>