#!/bin/bash # # phonebook, a companion cgi script for my phonebook stuff, which # searches a flat text file, and displays any matching lines in # HTMLized form. This utilizes my 'phone' bash script as well, # though any text file should work as a data source. This also # requires a JS capable user-agent. It is only suitable for relatively # small "phonebooks" of a few hundred or so names/numbers since the # entire list stays in memory so as to minimize list retrieval time. # The entire list is read into memory only once, and parsed from there. # JS Regular Expressions are used to dynamically narrow the list # on each keypress. Very fast. # # BUGS: Precautions to prevent 2 or more edits from happening at the # same time and stepping on each other, are non-existant. # # By: Hal Burgiss # # License: none. # ################################################################### # Data file with phone nums, names or whatever. We will read from, AND write # to this. This needs to be a plain text file, with one entry per line. # Permissions should be such that it can be written to, as well. Other than # that, whatever floats one's boat. datafile="/usr/share/phone/phones" # The script/command that generates our list text ... # This will have regex's applied against it. # cmd="cat $datafile | sort -f" cmd="/usr/local/bin/phone -f $datafile -list" title="Phonebook" generic="Phonebook" # Hardcoded password--the same for all users. password=phones # This password allows edit/write privileges, above does not. admin_pword=elfin whoami=$(basename $0) # cookie stuff cookie_name=$whoami name="new user" expires_int=10 cookie_date="expires="$(date --date "today +$expires_int days" +'%a, %d-%b-%Y 06:00:00 GMT') # getcolor='#dcf3f4' # Max number of regex's matches to display. Too many hits, and we # clutter the display, so will ignore excessive number of matches. def_hits=25 # Toggle depending on whether we have a valid, tested user. User is # allowed a) if a valid password is hanging on STDIN, or b) if a # cookie is present with the proper name. The cookie value is the user's # name. Cookie is written initially only on a password check. is_OK=false # check incoming [ -s /dev/stdin ] && std_in=$(cat /dev/stdin) # find and clean up the incoming, if its there ... # 2 ways to get in ... ########################################## # if [ -n "$std_in" ] && echo "$std_in" |grep "password\=" > /dev/null; then # somebody is trying a password attempt. if [ "$(echo $std_in |sed 's/.*password=//')" == "$password" ] ; then is_OK=true elif [ "$(echo $std_in |sed 's/.*password=//')" == "$admin_pword" ] ; then is_OK=true admin='&admin' fi name=$(echo $std_in |sed 's/name=//' |sed 's/\&.*//' |sed 's/+/ /') elif echo "$HTTP_COOKIE"|grep "\(^\|; \)$cookie_name=" >/dev/null ; then # if a cookie exists, we will trust it since cookies are only set on # password validation, and then get user's NAME from cookie. Cookies # are then renewed on every re-entry. name=$(echo $HTTP_COOKIE |sed "s/^.*$cookie_name=//" |sed "s/;.*//"|sed 's/\&admin//') if echo $HTTP_COOKIE |grep "$cookie_name=$name&admin" >/dev/null ; then name="$name" admin='&admin' fi is_OK=true fi if $is_OK && [ "$(echo $std_in |sed 's/=.*//')" == "new_pfile" ]; then # ie, we are writing new data with an update to $datafile. # Make a backup copy of datafile first: cp -f $datafile /tmp/$(basename $datafile)-$$ # Shake and bake: cat /dev/null > $datafile echo "$std_in" |perl -pe 's/(^.* .*$|^new_pfile=|^$)//s' >> $datafile fi if [ -n "$1" ]; then # somebody coming at us from another href search="$1" # make sure we have a cookie or password, and clean it up. $is_OK && search=$(echo $QUERY_STRING | sed 's/.*=//') fi if $is_OK; then # Get the entire list first, since its small, and # make a js compatible array from the file records. # Later we will regex just the ones we want from the full # list. data=$($cmd) alist=$(echo "$data"|perl -pe 's/(.*)\n/"$1",/;') # put a proper end on array to keep js happy. alist="$alist\"null\"" fi # Document stuff starts here ################################### # Put a cookie, if appropriate $is_OK && echo "Set-Cookie: $cookie_name=$name$admin; $cookie_date" # start building html/js. echo "Content-type: text/html" echo;echo # There are two modes: need password & have password. # The top of page and format is shared by both. cat << EOF $name's $title

Personal $title for $name

EOF # fork here depending on presence of qualified user/password. # Here, we need to get a password, and a user name. ! $is_OK && cat << EOF

     

EOF # Otherwise, we have a valid user, and good to go, so lets get # some matching list data and draw page accordingly. $is_OK && cat << EOF




EOF # only admin can edit $is_OK && [ -n "$admin" ] && cat << EOF
EOF $is_OK && cat << EOF


EOF # eof phonebook # set vi:nowrap