<?php
define
("TLVERSION""0.2.0.0dev");
define("TLREQUIRED_PHP_VERSION""4.3.0");
// Set these now, restore later.
$errorreporting error_reporting (E_ALL);
$errortrack ini_get("track_errors");
ini_set('track_errors'1);

$validipv4pattern  ":\/\/(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\."
 
."(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])"
 
"\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\/*";

// You REALLY don't want to edit below here unless you know what you're doing.

// ***************************************************************************

/**
 * Checks availability of required PHP version and for presence of required
 * PHP extensions.  Dies if extensions missing or PHP version too old.
 */
if (version_compare(phpversion(), TLREQUIRED_PHP_VERSION)<0) {
  die(
"$svcname Error: TightURL Library ".TLVERSION." needs PHP >= ".TLREQUIRED_PHP_VERSION." (you are using ".phpversion().")");
}

if (! 
extension_loaded('mysql')) {
  
die_HTML($svcname"Error: TightURL Library ".TLVERSION." needs the PHP MySQL module and it is not loaded.");
  exit;
}

if (! 
extension_loaded('pcre')) {
  
die_HTML($svcname"Error: TightURL Library ".TLVERSION." needs the PHP PCRE module and it is not loaded.");
  exit;
}

if (
file_exists("tighturl.urlpattern.inc.php")) {
  require_once(
"tighturl.urlpattern.inc.php");
//  validate_regex($bl);
}
if (
file_exists("tighturl.tltpattern.inc.php")) {
  require_once(
"tighturl.tltpattern.inc.php");
}
if (
file_exists("tighturl.blpattern.inc.php")) {
  require_once(
"tighturl.blpattern.inc.php");
}
if (
file_exists("tighturl.redirpattern.inc.php")) {
  require_once(
"tighturl.redirpattern.inc.php");
}
if (
file_exists("tighturl.ptcpattern.inc.php")) {
  require_once(
"tighturl.ptcpattern.inc.php");
}
if (
file_exists("tighturl.blippattern.inc.php")) {
  require_once(
"tighturl.blippattern.inc.php");
}

// ****** !All overridable configuration variables must go above this line! ******

/**
 * Anti-abuse system, network checks, URL checks are activated when in doubt.
 * User must set them to something other than TRUE to turn them off.
 */

if (! isset($antiabuse)) $antiabuse true;
if (! isset(
$netchecks)) $netchecks true;
if (! isset(
$mustexist)) $mustexist true;
if (! isset(
$validschemes)) $validschemes "(http|https|ftp|sftp)";
if (! isset(
$forbid)) $forbid "\.(cmd|bat|exe|scr|pif|vbs|js|pif|msi|cdr)";

/**
 * Checks current version of TightURL Library and/or Squish against version
 * information on SourceForge and http://tighturl.com/project sites.
 */
function TightURL_VersionCheck($versionuris) {
  
// Decided to forgo a proper XML parser for the sake of reducing bloat.

  
global $VUCycle;
  
  
// check http://tighturl.com/project/version.xml and/or http://tighturl.sourceforge.net/project/version.xml
  // parse out if there's a security release
  // notify admin of this tighturl installation once if there's a new version,
  // once a week, if there's a security fix.
  // Possibly display "newer version available" on templates.
  // Possibly disable vulnerable versions after a certain amount of time.
  // ie, only show "Site down for emergency maintenance. If you are the administrator, click here."
  // validate against mysql database password, show vulnerability screen.

  
if ($VUCycle 24$VUCycle 24;  // someone's trying to get banned.

  // ini_set('default_socket_timeout',    120);
  //file_get_contents("http://example.com/", 0, stream_context_create(array('http' => array('timeout' => 10))));
  
$xml TightURL_FetchVersionData("http://tighturl.com/project/version.xml");

}

/**
 * Retrieves TightURL and Squish version data from passed URL.
 * This URL must contain valid XML TightURL version data.
 */    
function TightURL_FetchVersionData($versionuri) {
  
// Decided to forgo the use of file_get_contents for the sake
  // of avoiding bloat and for PHP4 compatibility

  // Use fsockopen() for maximum compatibility with minimal requirements
  // supports timeout

  
preg_match("/^http:\/\/(.*?)\/(.*)/"$versionuri$matches); // ungreedy match
  
$host $matches[1]; $xml $matches[2];

  
$fp fsockopen($host80$errno$errstr5);
  if (! 
$fp) {
    return 
FALSE;  //error, do something with it, or not
  
}
  else {
    
stream_set_blocking($fpFALSE);
    
stream_set_timeout($fp10);
    
$out  "GET /".$xml." HTTP/1.1\r\n";
    
$out .= "Host: ".$host."\r\n";
    
$out .= "Connection: Close\r\n\r\n";

    
fwrite($fp$out);
    while (!
feof($fp)) {
       
$xml[]= fgets($fp1024);
    }
    
fclose($fp);
  }
  return (
$xml);
}

/**
 * Checks accepted URLs against URI blacklists and marks listed URLs as abused.
 * Defaults to checking the whole TightURL database unless a valid MySQL query
 * is supplied.  Returns TRUE if function succeeds, returns FALSE if anything
 * goes wrong or the anti-abuse system is turned off.
 */
function TightURL_KillBot($query='', &$error="") {

  global 
$dbtable$antiabuse$netchecks;

  if ((! 
$antiabuse) || (! $netchecks)) {
    
// Fail actively if someone's calling the killbot with anti-abuse off.
    
$error="TightURL Anti-abuse system or network tests are turned off!";
    return(
false);
  }
  
  if (
$query == ""$query="SELECT * FROM $dbtable;";

  
// Query records with status normal, and added within last 2 weeks or records with status normal and more than 7 hits and hit within the last 2 weeks
  //  "SELECT * FROM $dbtable where status=0 && (DATE_SUB(CURDATE(), INTERVAL 14 DAY) <= adddate || (hits > 7 && DATE_SUB(CURDATE(), INTERVAL 14 DAY) <= lasthit)) ORDER BY id;"
  
$set mysql_query($query);
  if (! 
$set) {
    
$error  mysql_error();
    return(
false);
  }
  
$rows = @mysql_num_rows($set) or $rows 0;

  for (
$i 0$i <$rows$i++) {

    
$row mysql_fetch_array($set);
    
$id $row["id"];
    
$url $row["url"];
    
$status $row["status"];
    
$hit URI_on_URIBL($url);
    if (
$hit) {
      
// Change this to disable instead of delete, delete at some future point.
      
$req ="update $dbtable set status=3 where id='$id';";
      
$res mysql_query($req);
    }
    else {
      
$req "update $dbtable set lastcheck=NOW(), checkcount=checkcount+1 where id='$id';"
      
$res mysql_query($req);
    }
  }
  return(
true);
}

function 
TightURL_IPonBL($ip) {

  global 
$ipbl$ipbluri$validipv4pattern$antiabuse$netchecks;

  
// Everything gets a pass if antiabuse or network tests are off.
  
if ((! $antiabuse) || (! $netchecks)) return(false);
        
  
$ipbls "";

  
// Test for IPv4 address, reverse the quads if found
  
if (preg_match("/^".$validschemes.$validipv4pattern."/"$uri$matches)) {
    
$domain=$matches[5] . "." $matches[4] . "." $matches[3] . "." $matches[2];
  }
  else {
    return(
FALSE);
  }
}

/**
 * Checks to see if a given URI is on a URI blacklist.
 * Currently this means SURBL (http://www.surbl.org) and URIBL (http://www.uribl.com)
 * 
 * Returns TRUE if the domain is listed on any configured URIBLs, returns FALSE if
 * anything goes wrong or the anti-abuse system is turned off.
 * 
 * A companion URI extractor must be written for the below issues
 * Must be changed to do full resolution of redirections on URI, simulating a browser
 * Must be changed to do IPv6 lookups
 * Must be changed to check multiple URIs (maybe a wrapper instead)
 * Must be changed to optionally check HTML entity encoded versions of URIs
 * Must be changed to handle URIBL's inclusion of some third-level domains.
 *
 */
function TightURL_URIonURIBL($uri) {

// This code does not yet properly implement a correct and efficient querying
// of URI BL data.

  
global $uribl$uribluri$validschemes$validurlpattern$validipv4pattern,
         
$antiabuse$netchecks$tltlds;

  
// Everything gets a pass if antiabuse or network tests are off.
  
if ((! $antiabuse) || (! $netchecks)) return(false);
        
  
$uribls "";

  if (
$uri) {
    
// Test for IPv4 address, reverse the quads if found
    
if (preg_match("/^".$validschemes.$validipv4pattern."/"$uri$matches)) {
      
$domain=$matches[5] . "." $matches[4] . "." $matches[3] . "." $matches[2];
    }
    else {
      
// strip out second-level domain name, *unless* on exception list,
      // in which case, strip out third level also and test that instead.
      // FIX: when testing uribl.com lists, also test additional level.  First hit wins.

      
preg_match("/^".$validschemes.$validurlpattern."$/"$uri$matches);
      
$domain $matches[4];
      if (
preg_match("/".$tltlds."$/"$domain$matches)) {$levels 2;} else {$levels 1;}
// (.*\..*){2} matches vnetworx.co.uk but not vnetworx.com
// .*(\.co\.uk) matches[1] .co.uk

      // klugey stripping routine to reduce domain to base domain name
      // expect regex wojuld be better

      
$ss countSubstrs($domain".");
      while (
$ss $levels) {
        
$chop strpos($domain".");
        
$domain substr($domain$chop 1);
        
$ss countSubstrs($domain".");
      }
    }

    
// Query URI blacklists to see if domain/IP appears as target in known spam
    // or something involved in a malware/phishing attack.
    
for ($i=0$i<count($uribl); $i++) {
      
$fqdn $domain "." $uribl[$i];
      
$recexists gethostbyname($fqdn); // ghbn weirdly returns the name on failure
      
if (($recexists != $fqdn) && preg_match("/^127\."$recexists)) {
        if (
$i 0$uribls .= ", ";                
        
$uribls .= $uribl[$i];      
      }
    }
    return (
$uribls); // change to return an array of indexes into the URIBL array
  
}
}

/**
 * Checks to see if a given URL is a Reserved URL.
 *
 * Returns TRUE if the ID is listed as a Reserved URL.
 */
function TightURL_OnReserve($decimal) {
  global 
$ReservedURL;

  
$res=FALSE;

  if (
$decimal) {
    
$sexatrigesimal base_convert($decimal1036);
    for (
$i=0$i<count($ReservedURL); $i++) {
      if (
$sexatrigesimal == strtolower($ReservedURL[$i])) return TRUE;
    }
    return 
FALSE;
  }
}

/**
 * Verifies the existence and accessibility of a resource in a given URL.
 * 
 * Returns FALSE if the resource does not exist or cannot be accessed using
 * supplied authentication information, else returns the resolved and verified
 * URL.  Given URL is returned as resolved to itself if $netchecks are off.
 *
 * Will recurse through redirection chains up to 12 times by default.  This
 * value is preferably selectable by the user in a configuration screen
 * somewhere, but probably should not be lower than 12, as attempts are made
 * to detect HTML and JavaScript redirects in addition to HTTP redirects, and
 * a dozen redirects to find the end is quite possible.
 *
 * Unfortunately Google's GFE server erroneously returns 404 errors when
 * they should be returning something like a 405, making it impossible to
 * use HTTP HEAD to verify the existence of resources front-ended by GFE.
 * Additionally Amazon throws a 405 attempting to HEAD some of their resources
 * so this function does not attempt to use HEAD at all.
 *
 * BUG: Presently only does HTTP
 *
 */
function TightURL_Resolve_URL ($url$chain=12, &$resolvedchain=array("")) {
//  $resolvedchain = array($url);

  
global $netchecks;

  
$post "";

  if (! 
$netchecks) {
    
// If network checks off, accept submitted URL as resolved.
    
return($url);
  }

  
$parsed parse_url($url);

  
$pre  = isset($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '' '//') : '';
  
$pre .= isset($parsed['user']) ? $parsed['user'].(isset($parsed['pass']) ? ':'.$parsed['pass'] : '').'@' '';
  
$pre .= isset($parsed['host']) ? $parsed['host'] : '';
  
$pre .= isset($parsed['port']) ? ':'.$parsed['port'] : '';
  if(isset(
$parsed['path']))
    
$post = (substr($parsed['path'], 01) == '/') ? $parsed['path'] : ('/'.$parsed['path']);
  else
    
$post "/";  
  
$post .= isset($parsed['query']) ? '?'.$parsed['query'] : '';
  
$post .= isset($parsed['fragment']) ? '#'.$parsed['fragment'] : '';

  
$resolved false;

  
// Change this to support all protocols TightURL supports, not just HTTP
  
if (! isset($parsed['port']) || $parsed['port'] == 0$parsed['port'] = 80;
  
$ip gethostbyname($parsed['host']); // This is supposed to avoid unnecessary DNS lookups
  
if($connection = @fsockopen ($ip$parsed['port'], $errno$errstr5)) {
    
stream_set_timeout($connection5);
    
// HTTP send Connection: Close so we don't have to wait
    // Google's GFE handling of HEAD is broken, and Amazon returns 405 on HEAD so had to use GET
    
fwrite($connection"GET ".$post." HTTP/1.0\r\nHost: ".$parsed['host']."\r\nConnection: Close\r\n\r\n");
    while (!
feof($connection)) {
      
$line_read=fgets($connection);
      if (
$line_read == "") break; //blank line is header delimiter, if you see it you're done here
                                   //Fix: change this and start parsing the body for HTML-based redirections.

      
if (preg_match("/HTTP\/\S* +(\S*) /"$line_read$matches)) { // Look for certain HTTP status codes
        
switch ($matches[1]) {
        case 
200// Ok, we have a final destination (as far as HTTP is concerned)
        
case 201// Created, we have a final destination
        
case 202// Accepted, we have a final destination
        
case 203// Non-authoritative reply, we have a final destination
        
case 204// No content, we have a final destination
        
case 205// Reset content, we have a final destination
        
case 206// Partial content, we have a final destination
        
case 207// Multi-status, we have a final destination
        
case 304// Not Modified (this is ok)
        
case 401// Authorization required (this is ok)
        
case 402// Payment required (this is ok)
        
case 403// Forbidden (but also ok)
        
case 405// Method not allowed (but also ok)
        
case 406// Not acceptable (acceptable here unless someone tells us otherwise)
        
case 409// Conflict (acceptable unless someone tells us otherwise)
        
case 421// Too many connections (fail ok)
        
case 426// Use TLS (fail ok)
        
case 500// Internal server error (fail ok)
        
case 502// Bad gateway (fail ok)
        
case 503// Service unavailable (fail ok)
        
case 504// Gateway timeout (fail ok)
        
case 505// HTTP version not supported (fail ok)
        
case 509// Bandwidth exceeded pseudo code (fail ok)
          
$resolved $url;
          
$resolvedchain[] = $url;
          break 
2;
        case 
300:
        case 
301:
        case 
302:
        case 
307:
          break;
        case 
404// Not found
        
case 408// Request timeout (this URL will never work again)
        
case 410// Gone (and not coming back)
          
break 2;
        default:
          
$resolved $url;
          
$resolvedchain[] = $url;
          break 
2;          
        }
      }

      
// If this is a redirect (300, 301, 302, 307), follow it if the chain isn't too long
      
if (preg_match("/Location: (.*)\r\n/"$line_read$matches)) {
        
fclose($connection);
        
$connection false;
        
$resolvedchain[] = $url;
        if (
$chain $resolved TightURL_ResolveURL($matches[1], $chain 1$resolvedchain);
        break;
      }

    }
    
// Parse body here?
    
if ($connectionfclose($connection);
  }
  return(
$resolved);
}

/**
 * Save the given URL in the database if unique and return the ID or return an existing ID for given URL.
 * Returns FALSE if anything goes wrong doing this, and sets an error code.
 *
 * Codes are:
 * 0 - Success
 * 1 - Database error
 * 2 - Invalid URL
 * 3 - Can't shorten
 * 4 - Self-referential URLs not allowed
 * 5 - Redirector
 * 6 - Forbidden type
 * 7 - Policy violation
 * 8 - Blacklisted
 * 9 - Unresolvable
 *
 * The ID returned will be a sexatrigesimal (Base-36) number.
 *
 */
function TightURL_SaveURL($decodedurl, &$errcode) {
  global 
$dbtable$validurlpattern$validschemes$forbid$redir$bl$remote,
         
$antiabuse$netchecks$mustexist$self$selfsite$aliassite;

// Pass in base length instead of URL, if zero assume you can shorten it, return length of sexagesimal.
// Pass in IP address, if blank do not check internal IP blacklist.

  
$errcode false;

  
// Below fixes www put into tighturl.com but does it fix tighturl.com put into www? (probably not)
  // Also have to make www. screening optional!
  // site: tighturl.com     reject: www.tighturl.com and tighturl.com
  // site: www.tighturl.com reject: www.tighturl.com and tighturl.com (won't work, no match for tighturl.com)
//  echo "s: ".$selfsite.$self." decoded: ".$decodedurl."\n";
//  $m = "|".$selfsite.$self."|i";
//  $v = preg_match("/".$selfsite.$self."/i", $decodedurl, $matches);
//  echo "matches1: ".$matches[0]." return: ".$v." m: ".$m."\n";
  
if (preg_match("|".$selfsite.$self."|i"$decodedurl) || preg_match("|^www\.".$selfsite.$self."|i"$decodedurl) ||
                  ((
$aliassite != "") && preg_match("|^".$aliassite.$self."|i"$decodedurl)|| preg_match("|^www\.".$aliassite.$self."|i"$decodedurl))) {
    
// No URLs that point to ourselves, fail.
    
$errcode 4;
    return(
false);
  }
  elseif (! 
preg_match("/^".$validschemes.$validurlpattern."$/"$decodedurl)) {
    
// Invalid URL, fail.
    
$errcode 2;
    return(
false);
  }
  elseif (isset(
$forbid) && ($forbid != "") && (preg_match("/.*".$forbid."$/i"$decodedurl))) {
    
// Executable or other forbidden type, fail.
    
$errcode 6;
    return(
false);
  }
  
// do an image comparison against known spam images here(?) and only if antiabuse is on (netchecks can be off)
  
elseif (isset($bl) && ($bl != "") && (preg_match("/.*".$bl.".*/i"$decodedurl))) { // delete this crap
    // URL that violates policy, fail.
    
$errcode 7;
    return(
false);
  }
  elseif (isset(
$ipbl) && ($ipbl != "") && (preg_match("/.*".$ipbl.".*/i"$ip))) {
    
// IP address of policy violator, fail.
    
$errcode 7;
    return(
false);
  }
  elseif (isset(
$redir) && ($redir != "") && (preg_match("/.*".$redir.".*/i"$decodedurl))) {
    
// It's another known redirector, fail.
    
$errcode 5;
    return(
false);
  }
  elseif (isset(
$mustexist) && $mustexist && isset($netchecks) && $netchecks) {
    
// Check to see if link exists
    
$resolved TightURL_Resolve_URL($decodedurl);
    if (
$resolved) {
      
$decodedurl $resolved;
    }
    else{
      
// URL could not be resolved (does not exist)
      
$errcode 9;
      return(
false);
    }  
  }
  else {
    
$safeurl sanitize_sql_string($decodedurl);
    
$result = @mysql_query("SELECT MAX(id) FROM $dbtable") or display_HTML("""""Error: $svcname system error."$decodedurl""$decodedurl);
    
$lastid = @mysql_result($result0) + 1;
    
$guesssexatrigesimal base_convert($lastid1036);
    
$guesstighturl "http://" $_SERVER['HTTP_HOST'] . $self;
    if (! 
$FOFMethod$guesstighturl .= "?i=";  // We need the parameter tag
    
$guesstighturl .= $guesssexatrigesimal// Append the Base-36 ID to the URL
    
if ($aliassite != "") {
      
$guesstighturlalias  "http://" $aliassite;
      if (! 
$FOFMethod$guesstighturlalias .= "?i=";  // We need the parameter tag
      
$guesstighturlalias .= $guesssexatrigesimal;
    }
    if ( 
strlen($guesstighturl) >= strlen($decodedurl) || (($aliassite != "") && strlen($guesstighturlalias) >= strlen($decodedurl))) {
      
// Can't shorten URL
      
$errcode 3;
      return(
false);
    }
    else {
    
// This needs to be changed to check everything in the resolvedchain
    
if ($antiabuse) echo "yay for antiabuse!\n";
    if (
$antiabuse) {$lists TightURL_URIonURIBL($decodedurl);} else {$lists false;}
      if (! 
$lists) {
        
$rows=0$srows=0$testurl=$safeurl;
        if (
preg_match("/\/$/"$testurl)) $testurl rtrim($testurl,"/");
        
$req "SELECT * FROM $dbtable WHERE url = '$testurl/';";
        
$res mysql_query($req);
        
$srows = @mysql_num_rows($res) or $srows 0;
        if (
$srows == 0) {
          
$req "SELECT * FROM $dbtable WHERE url = '$testurl';";
          
$res mysql_query($req);
          
$rows = @mysql_num_rows($res) or $rows 0;
        }
        if (
$rows == && $srows == 0) {
          do {
            
$req ="INSERT INTO $dbtable (id, url, adddate, addip) ";
            
$req .= "VALUES ('', '$safeurl', NOW(), '$remote');";
            if (
mysql_query($req)) {
              
$decimal mysql_insert_id();
            }
            else {
              
die_HTML($svcname"Error: Database failure.");
            }
            
$reserved_id on_Reserve($decimal);
            if (
$reserved_id) {
              
// Delete this record so it doesn't override the reserved ID. (?)
              
$req "DELETE FROM $dbtable WHERE id = '$decimal';";
              
$res mysql_query($req) or die_HTML($svcname"Error: Database failure.");
            }
          } while (
$reserved_id);
        }
        else {
          
// Return existing ID for this duplicate request
          // Too much work is being done prior to this
          // Also, take opportunity to update status on this URL
          
$decimal mysql_result($res0"id");
        }
        
$sexatrigesimal base_convert($decimal1036);
//        $address = "http://" . $_SERVER['HTTP_HOST'] . $self;
        
$address "http://" $selfsite $self;
        if (! 
$FOFMethod$address .= "?i=";  // We need the parameter tag
        
$address .= $sexatrigesimal// Append the Base-36 ID to the URL
        
if ((strlen($address) <= strlen($decodedurl)) && ($aliassite != "")) {
          
$address "http://" $aliassite $self;
          if (! 
$FOFMethod$address .= "?i=";  // We need the parameter tag
          
$address .= $sexatrigesimal// Append the Base-36 ID to the URL
        
}
        
display_HTML("""save"""$decodedurl$address);
      }
      else {
        
// Blacklisted in a URI BL, fail.
        
$errcode 8;
        return(
false);
      }
    }
  }
}


/**
 * Looks up given ID in the database, expects the ID to be a sexatrigesimal (Base-36) number,
 * which is the format used by TightURLs.
 *
 * We convert the ID to decimal before looking it up in the database, as the
 * ID field is a MySQL autoincrement decimal value.
 *
 * Set $hit TRUE if a hit should be recorded for this request.  Defaults to FALSE. 
 *
 * Returns the URL that corresponds to the TightURL ID, and sets $status to the URL's current status.
 *
 */
function TightURL_LookupID($conn$dbtable$sexatrigesimal, &$status$hit=false) {

  
// Returns: -256 Error, -255 Not Found, -1 Reserved/Template, or status field from the found record

  
if (preg_match("/(.*?)\/(.*)/"$sexatrigesimal$matches)) $sexatrigesimal $matches[1];

  
$decimal base_convert ($sexatrigesimal3610);
  
$req "SELECT url, status FROM $dbtable WHERE id = '$decimal';";

  
$res mysql_query($req$conn);
  if (! 
$res) {
    
$status = -256;
    return(
"");
  }
 
  
$rows mysql_num_rows($res);
  if ((
$rows != 0) && (mysql_result($res0"url") != "")) {
    
$url mysql_result($res0"url");
    
$status mysql_result($res0"status");
    if (
$hit) {
      
$req ="update $dbtable set lasthit=NOW(), hits=hits+1 where id='$decimal';";
      
$res mysql_query($req$conn);
    }
    return(
$url);
  }
  elseif (
TightURL_OnReserve($decimal)) { // It's a(n implied) Reserved URL
    // This is a template or an API
    
$status = -1;
    return(
false);
  }
  else { 
// Not found, Not on reserve
    
$status = -255;
    return(
false);
  }
}

function 
TightURL_ApiREST() {
  return (
false);
}

function 
TightURL_ApiXMLRPC() {
  return (
false);
}

function 
TightURL_ApiSOAP() {
  return (
false);
}



// ***************** Non-TightURL-specific functions *********************

/**
 * Counts the number of times a substring is contained in a given string.
 */
if (! function_exists('countSubstrs')) {
  function 
countSubstrs($haystack$needle) {
    return ((
$p strpos($haystack$needle)) === false) ? : (countSubstrs(substr($haystack$p+1), $needle));
  }
}

//unset($php_errormsg);
//@preg_match($pattern, ""); /*actually give the pattern a try! */
//$ret=isset($php_errormsg) ? $php_errormsg : false;
//ini_set('track_errors', 0);
//if ($errortrack) $php_errormsg = isset($phperrormessage) ? $phperrormessage : false;
//return($ret);
?>