$ctoken) { // return the user's bookmark list if server token is greater. $res = my_mysql_query("select path, url from link, bookmarks where bookid = book_id ". "and person_id = '$ID' and expiration is NULL order by path"); // tell the client data is coming. echo "*T," . $stoken . "\r\n*B\r\n"; // and send it all in. while ($data = mysql_fetch_assoc($res)) { debug("\"$data[path]\",\"$data[url]\"\r\n"); echo "\"$data[path]\",\"$data[url]\"\r\n"; } echo "*Z\r\n"; end_script("Finished sending server bookmarks."); } // Bookmarks seem up to date, // let's process the add/delete/ // mkdir directives now. else { // if there are commands in the client's // content data, then let's process them. if (strlen($content) > 0){ do { // TODO: This seems like a really odd-construct to me - looping // until we receive an positive from the parseline routine. shouldn't // we instead loop through all the "lines" in the content, ending // the loop naturally when we've exceeded all of them? $i = strpos($content,"\r\n"); if ($i == 0) { break; } $bm_row = substr($content,0,$i); // get the current bookmark and send it to be parsed. if (parseline($bm_row, $ID)){ echo "*Z\r\n"; end_script("'parseline' returned a positive value."); } // this bookmark is finished, so pop it off our list. $content = substr($content,strlen($content)-(strlen($content)-$i-1)); } while (true); // with our updates finished, we update the token and move on. my_mysql_query("update person set token = token+1, lastchanged = now() where personid='$ID'"); $res = my_mysql_query("select token from person where personid='$ID'"); // get the new server token for client updating. $data = mysql_fetch_assoc($res); $stoken = $data["token"]; // return new server token. echo "*T," . $stoken . "\r\n"; } } echo "*Z\r\n"; end_script("*** Finished client operation. ***"); // parses bookmark list line, // processes adds and deletes. function parseline($bm_row,$ID) { debug("raw: $bm_row"); // debugging love. if (get_magic_quotes_gpc() == 1) { // auto-escape is on... $bm_row = stripslashes($bm_row); } // so remove extra slashes. debug("final: $bm_row"); // debugging love. $bm_row = trim($bm_row); // get rid of ooky whitespace. $cmd = substr($bm_row,0,1); // first char is what command to perform. $bm_row = substr($bm_row,3); // strip token of COMMAND,COMMA,SLASH. $l = strpos($bm_row,"\""); // find the end of our bookmark path. $tpath = substr($bm_row,0,$l); // and save the path itself into $tpath. $path = addslashes($tpath); // encode slashes and apostraphes for SQL. // add bookmark if ($cmd == "A") { $url = substr($bm_row,strlen($tpath)+3); // get the URL from our row. $url = trim($url,"\"\r\n"); // remove ookiness and junk. $surl = substr($url,7,55).substr($url,-200); // MySQL indexes can only be 255. // insert the bookmark. my_mysql_query("insert into bookmarks (url, surl) values ('$url', '$surl')"); $res = my_mysql_query("select bookid from bookmarks where surl='$surl'"); // and check the expiration date. deleted URLs should // be regularly purged from the database after a certain // amount of time, but if the current URL is set to be // deleted, but hasn't yet, we resurrect it. if ($data = mysql_fetch_assoc($res)) { $bid = $data['bookid']; // shorter. $res = my_mysql_query("insert into link (expiration, person_id, access, path, ". "book_id) values (NULL, '$ID', now(), '$path', '$bid')"); // bookmark exists already, but expired. Unexpire! if (!$res) { my_mysql_query("update link set expiration = NULL, book_id = '$bid' " . "where person_id = '$ID' and path = '$path'"); } } } // delete it by setting expiration // date. this allows us to undelete // before a certain time period passed. else if ($cmd == "D") { my_mysql_query("update link set expiration = now() where path = '$path' and person_id = '$ID'"); } // make directory, catering // to previously expired ones. else if ($cmd == "M") { $res = my_mysql_query("insert into link (expiration, person_id, access, ". "path) values (NULL, '$ID', now(), '$path')"); if (!$res) { // resurrect a deleted directory. my_mysql_query("update link set expiration = NULL, book_id = NULL ". "where person_id = '$ID' and path = '$path'"); } } // remove directory by setting // the expiration date to now. else if ($cmd == "R") { my_mysql_query("update link set expiration = now() where path = '$path' and person_id = '$ID'"); } // bah! else { echo "*E\r\nInvalid Bookmark Command: $cmd \r\n"; debug("Invalid Bookmark Command: [$cmd]."); return true; } return false; } // merely a wrapper around all our SQL queries so that // we can handle whether a line to our debug should happen. function my_mysql_query($str) { debug($str); // fun! $res = mysql_query($str); return $res; } // merely prints the passed // string to a debug file. function debug($str) { global $debug, $debug_fh; if (!$debug) { return; } $date = date("D M j G:i:s T Y"); fputs($debug_fh, "[$date] $str\r\n"); } // end this puppy! function end_script($str) { global $debug, $debug_fh; if ($debug) { debug($str); fclose($debug_fh); } exit; // good bye, so sad to see you go. } ?>