#!/usr/bin/php -q
<?php
// srpm script to build/query database of rpm source code
// copyright (c) 2005 Stew Benedict <sbenedict@mandriva.com>

$srpm_version = '0.02';
$src_date = 'Mar 22 2006';
$copyright = '(c) 2005';
$author = 'Stew Benedict <sbenedict@mandriva.com>';

error_reporting( E_ERROR );

$debug = FALSE;
$verbose = FALSE;
$progress = FALSE;
$quiet = FALSE;
$skip_tar = FALSE;
$source_only = FALSE;
$show_patch = FALSE;
$update_db = FALSE;
$do_count = FALSE;
$extra_info = FALSE;
$hide_tag = FALSE;
$no_case = FALSE;

$db_access = array();

// for progress
$p = array();
$bs = "12" ^ "9";
$p[1] = $bs . "|";
$p[2] = $bs . "/";
$p[3] = $bs . "-";
$p[4] = $bs . "\\";
$pstate = 1;
$lprefix = '';

function print_help($self) {    
    printf("Usage: %s [-h] [-v] [-c <directory>] [-f <file>] [-q <substring>] [-t <tag>]\n\n", $self);
    printf("  -h  Prints this help\n");
    printf("  -a  <path> Add a src.rpm entry with <tag> to the database\n");
    printf("  -c  <directory> Create database entries with <tag> from a src.rpm <directory>\n");
    printf("  -C  Only output the count of query matches\n");
    printf("  -d  Debugging output\n");
    printf("  -D  <tag> Delete all <tag> entries\n");
    printf("  -e  Show extra info (version, release, date)\n");
    printf("  -f  <file> Examine a src.rpm file and output to stdout\n");
    printf("  -i  Case insensitive search\n");
    printf("  -I  Initialize database\n");
    printf("  -l  List database tags\n");
    printf("  -p  List patched files\n");
    printf("  -P  Show processing progress\n");
    printf("  -q  Query database for substring match\n");
    printf("  -Q  Quiet query - show tag and package name only (or numeric count only)\n");
    printf("  -r  Rebuild databse to reclaim space\n");
    printf("  -t  <tag> Tag for created database entries or database queries\n");
    printf("  -T  Suppress Tag and Path label output for queries\n");
    printf("  -u  <tag> Update <tag> entries (new/removed files in directory)\n");
    printf("  -s  Skip tarfile extract\n");
    printf("  -S  Limit query to source files (no patches)\n");
    printf("  -v  Verbose output\n");
    printf("  -V  Version\n");
    printf("  Additional arguments are treated as files (like -f)\n");
    exit(0);
}

function p_debug($string, $var) {
	global $debug;
	if ($debug) printf("$string", $var);
}

function p_verbose($string, $var) {
	global $verbose;
	if ($verbose) printf("$string", $var);
}

function s_progress($prefix) {
	global $verbose, $debug, $progress, $p, $pstate, $lprefix;
	if (!$verbose && !$debug && $progress) {
		if (!$prefix) {
			print($p[$pstate]);
			$pstate = $pstate + 1;
			if ($pstate > 4)
				$pstate = 1;
			return;
		}
		if ($prefix != 'files' && $prefix != 'sources' && $prefix != '') {
			printf("%-40s", $prefix . ":");
			$pstate = 1;
			return;
		} elseif ($prefix != $lprefix) {
			print("\t$prefix: ");
			$lprefix = $prefix;
			return;
		}
	}
}

function perror($str) {
	global $progress;
#	if ($progress)
#		print("\n");
	print("$str");
}

function read_rcfile() {
	// look for rcfile
	global $self;
	$rcfile = $_ENV['HOME'] . "/.srpmrc";
	$fh = fopen($rcfile, 'r');
	if ( $fh ) {
		while (!feof($fh)) {
			$buff = fgets($fh, 4096);
			$values = preg_split("/[\s]+/", $buff);
			if ($values[0])
				$db[$values[0]] = $values[1];
		}
		fclose($fh);
		return $db;
	} else {
		die( "$self error: fopen failed for $rcfile\n" ) ;
	}
}

function check_sqlite() {
	if (!extension_loaded("sqlite")) {
		dl("sqlite.so");
		if (!extension_loaded("sqlite"))
			exit("Please enable SQLite support\n");
	}
}

function get_dbfile() {
	global $self;
	$db_dir = $_ENV['HOME'] . "/.srpm";
	if (!is_dir($db_dir))
		mkdir("$db_dir", 0770) or die("$self error: can't create $db_dir\n");
	$db_file = $db_dir . "/srpm.sqlite";
	return $db_file;
}

function open_db() {
	check_sqlite();
	$db_file = get_dbfile();
	if (!is_file($db_file)) {
		perror("warning: can't find $db_file, will create new db...\n");
		$no_db = TRUE;
	}
	$s = sqlite_open("$db_file", 0660, $err);
	if ($no_db)
		make_tables($s);
	return $s;
}

function close_db($s) {
	sqlite_close($s);
}

function create_db() {
	global $self;
	$s = open_db();
	make_tables($s);
	close_db($s);
}

function make_tables($s) {
	$r = sqlite_query("create table Tags ( tag TEXT PRIMARY KEY, path TEXT UNIQUE, tdate TEXT )", $s);
	$r = sqlite_query("create table Packages ( record INTEGER AUTOINCREMENT PRIMARY KEY, tag TEXT, package TEXT, version TEXT, release TEXT, pdate TEXT )", $s);
	$r = sqlite_query("create table Sources ( record INTEGER, type TEXT, srecord INTEGER AUTOINCREMENT PRIMARY KEY, pfile TEXT )", $s);
	$r = sqlite_query("create table Files ( record INTEGER, srecord INTEGER, sfile TEXT )", $s);
}

function rq($str) {
	// re-quote a string
	return "'" . $str . "'";
}

function add_package_record($s, $tag, $path) {
	$rtags = `rpm -qp --nosignature --qf '%{name}|%{version}|%{release}|%{buildtime}' $path`;
	$tlist = split("\|", $rtags);
	//print_r($tlist);
	$tag = rq($tag);
	$path = basename($path);
	$package = rq($tlist[0]);
	$version = rq($tlist[1]);
	$release = rq($tlist[2]);
	$pdate = rq($tlist[3]);
	$r = sqlite_query("select tag, package, version, release from Packages where tag = $tag and package = $package and version = $version and release = $release", $s);
	if (sqlite_num_rows($r) >= 1) {
		perror("Error: file $tlist[0]-$tlist[1]-$tlist[2] already in the database under tag $tag...\n");
		return 0;
	}
	$r = sqlite_query("insert into Packages (tag, package, version, release, pdate) VALUES($tag, $package, $version, $release, $pdate)", $s);
	s_progress($path);
	$r = sqlite_query("select record from Packages where tag = $tag and package = $package", $s);
	if (sqlite_num_rows($r) >= 1) {
		$row = sqlite_fetch_array($r, SQLITE_ASSOC);
    	return $row['record'];
	} else {
		perror("Error: adding file $path failed...\n");
	}
}

function add_source_records($s, $record, $sfiles) {
	global $verbose;
	s_progress("sources");
	foreach ($sfiles as $pfile) {
		s_progress();
		$ftype = "";
		if (eregi("patch.bz2$|patch.gz$|patch$", $pfile))
			$ftype = "P";
		if (eregi("tar.bz2$|tar.gz$|tar$", $pfile))
			$ftype = "S";
		if ($pfile == "")
			return;
		if ($verbose)
			printf("Source: %s, Type: %s\n", $pfile, $ftype);
		$ftype = rq($ftype);
		$pfile = rq($pfile);
		$r = sqlite_query("insert into Sources (record, type, pfile) VALUES($record, $ftype, $pfile)", $s);
	}
}

function add_file_records($s, $record, $sfiles) {
	global $verbose;
	foreach ($sfiles as $sfile) {
		$good_src = FALSE;
		if (eregi("patch.bz2$|patch.gz$|patch$", $sfile)) {
			$flist = patch_list($sfile);
			$good_src = TRUE;
		}			
		if (eregi("tar.bz2$|tar.gz$|tar$", $sfile)) {
			$flist = tar_list($sfile);
			$good_src = TRUE;
		}			
		if ($sfile == "")
			return;
		// only proceed for tarballs and patches
		if ($good_src) {
			$files = spliti("\n", $flist);
			// get the srecord# for this source from the db
			$sfile = rq($sfile);
			$r = sqlite_query("select srecord from Sources where record = $record and pfile = $sfile", $s);
			if (sqlite_num_rows($r) >= 1) {
				$row = sqlite_fetch_array($r, SQLITE_ASSOC);
    			$srecord = $row['srecord'];
			} else {
				perror("Error: adding files from $sfile failed...\n");
			}
			s_progress("files");
			foreach ($files as $dfile) {
				if (strlen($dfile)) {
					s_progress();
					if ($verbose)
						printf("File: %s\n", $dfile);
					$dfile = rq($dfile);
					$r = sqlite_query("insert into Files (record, srecord, sfile) VALUES($record, $srecord, $dfile)", $s);
				}
			}
		}
	}
}

function add_record($tag, $path) {
	global $progress, $verbose;
	// corrupts add data - not needed
	if ($verbose)
		$verbose = FALSE;
	$cur_dir = getcwd();
	$path = fix_path($path, $cur_dir);
	p_debug("Path:\t%s\n", $path);
	check_file($path);
	$s = open_db();
	p_debug("Add package record for: %s\n", $path);
	$record = add_package_record($s, $tag, $path);
	if (!$record) {
		close_db($s);
		return;
	}
	p_debug("Add source records for package record: %s\n", $record);
	$sfiles = rpm_list($path);	
	$files = spliti("\n", $sfiles);
	add_source_records($s, $record, $files);
	$cpio_dir = make_tmp_dir();
	get_all_files($path);
	add_file_records($s, $record, $files);
	chdir($cur_dir);
	clean_tmp_dir($cpio_dir);
	close_db($s);
	if ($progress)
		print("\n");
}

function add_tag_record($tag, $path) {
	$s = open_db();
	p_debug("Add tag record $tag for: %s\n", $path);
	$tag = rq($tag);
	$path = rq($path);
	$cur_date = rq(date("D M j G:i:s T Y"));
	$r = sqlite_query("insert into Tags (tag, path, tdate) VALUES($tag, $path, $cur_date)", $s);
	if (sqlite_error_string(sqlite_last_error($s)) == "constraint failed") {
		perror("Error: tag $tag or path $path already in Tags...\n");
		return 1;
	}
	close_db($s);
	return 0;	
}

function add_source_directory($tag, $path) {
	$path = fix_path($path, getcwd());
	$new_tag = add_tag_record($tag, $path);
	if ($new_tag)
		exit(1);
	foreach (glob("$path/*.src.rpm") as $src_rpm) {
		add_record($tag, $src_rpm);
	}
}

function check_for_tag($tag, $path) {
	$s = open_db();
	$qtag = rq($tag);
	$path = fix_path($path, getcwd());
	$path = dirname($path);
	$r = sqlite_query("select DISTINCT tag, path from Tags where tag = $qtag", $s);
	$exists = sqlite_num_rows($r);
	close_db($s);
	if ($exists >= 1) {
		$row = sqlite_fetch_array($r, SQLITE_ASSOC);
		if ($row[path] != $path)
			die("Tag ($tag) already in database with path: $row[path]\n");
		return TRUE;
	} else {
		return FALSE;
	}
}

function add_tag_path($tag, $path) {
	$path = fix_path($path, getcwd());
	$path = dirname($path);
	$new_tag = add_tag_record($tag, $path);
	if ($new_tag)
		exit(1);
}

function list_tags() {
	$s = open_db();
	$r = sqlite_query("select * from Tags order by tag", $s);
	while ($row = sqlite_fetch_array($r, SQLITE_ASSOC)) {
		printf("%-12s%-40s%-18s\n", $row[tag], $row[path], $row[tdate]);
	}
	exit(0);
}

function rebuild_database() {
    // rebuild db to reclaim space
    $s= open_db();
    s_progress("Rebuilding database");
    p_verbose("Rebuilding database...\n");
    $r = sqlite_query("VACUUM", $s);
    close_db($s);
}

function delete_tag_entries($tag) {
    // delete all entries with given tag
    global $progress;    
    $s= open_db();
    $qtag = rq($tag);
    $to_remove = array();
    $r = sqlite_query("select * from Tags where tag = $qtag", $s);
    if (sqlite_num_rows($r) >= 1) {
        s_progress($tag);
        p_verbose("Remove $qtag from Tags...\n");
        $r = sqlite_query("delete from Tags where tag = $qtag", $s);
        $r = sqlite_query("select DISTINCT record from Packages where tag = $qtag", $s);
		while ($row = sqlite_fetch_array($r, SQLITE_ASSOC)) {
			array_push($to_remove, $row[record]);
		}
        if (sizeof($to_remove) > 0) {
            $nrecs = sizeof($to_remove);
    		p_verbose("Removing $nrecs tagged Packages, Sources, Files entries for $qtag...\n");
    		foreach($to_remove as $rnum) {
                s_progress();
    			$qnum = rq($rnum);
    			$v = sqlite_query("delete from Packages where record = $qnum", $s);
    			$v = sqlite_query("delete from Sources where record = $qnum", $s);
    			$v = sqlite_query("delete from Files where record = $qnum", $s);
    		}
    	}
        close_db($s);
        // reclaim the space - don't bother for a smallish transaction
        if ($nrecs > 500) {
            if ($progress)
                print("\n");
            rebuild_database();
        }
        if ($progress)
            print("\n");
    } else {
        perror("Error: no Tag entry found for $qtag\n");
    }       
}

function update_tag_entries($tag) {
	// walk through a listed tag dir and add/remove packages that have changed
	$s = open_db();
	$qtag = rq($tag);
	$to_remove = array();
	$to_add = array();
	$r = sqlite_query("select DISTINCT path from Tags where tag = $qtag", $s);
	if (sqlite_num_rows($r) >= 1) {
		$row = sqlite_fetch_array($r, SQLITE_ASSOC);
		$spath = $row[path];
		p_verbose("Update $qtag entries from %s...\n", $spath);
		// get the existing entries
		$t = sqlite_query("select DISTINCT record, tag, package, version, release from Packages where tag = $qtag", $s);
		while ($row = sqlite_fetch_array($t, SQLITE_ASSOC)) {
			$pname = $row[package] . "-" . $row[version] . "-" . $row[release] . ".src.rpm";
			p_verbose("Check for $pname in $spath...");
			if (file_exists($spath . "/" . $pname)) {
				p_verbose("OK\n");
			} else {
				p_verbose("remove\n");
				array_push($to_remove, $row[record]);
			}
		}
		foreach (glob("$spath/*.src.rpm") as $src_rpm) {
			p_verbose("Check for $src_rpm in db...");
			$rtags = `rpm -qp --nosignature --qf '%{name}|%{version}|%{release}' $src_rpm`;
			$tlist = split("\|", $rtags);
			$package = rq($tlist[0]);
			$version = rq($tlist[1]);
			$release = rq($tlist[2]);
			$u = sqlite_query("select package from Packages where tag = $qtag and package = $package and version = $version and release = $release", $s);
			if (sqlite_num_rows($u) >= 1) {
				p_verbose("OK\n");	
			} else {
				p_verbose("add\n");
				array_push($to_add, $src_rpm);
			}
		}
		
	} else {
		perror("Error: no Tag entry found for $qtag\n");
	}
	if (sizeof($to_remove) > 0) {
		p_verbose("Removing tagged entries for $qtag...\n");
		foreach($to_remove as $rnum) {
			$qnum = rq($rnum);
			$v = sqlite_query("delete from Packages where record = $qnum", $s);
			$v = sqlite_query("delete from Sources where record = $qnum", $s);
			$v = sqlite_query("delete from Files where record = $qnum", $s);
		}
	}
	if (sizeof($to_add) > 0) {
		p_verbose("Adding tagged entries for $qtag...\n");
		foreach($to_add as $src_rpm) {
			add_record($tag, $src_rpm);
		}
	}
	close_db($s);
}

function do_query($q_str) {
	global $source_only, $db_tag, $quiet, $debug, $do_count, $extra_info, $hide_tag, $no_case;
	$s = open_db();
	p_verbose("Query package records for: %s\n", $q_str);
	$query = "select DISTINCT tag, package, version, release, pdate, type, pfile, sfile from Files JOIN Sources USING (srecord) JOIN Packages using (record) where sfile ";
 	if ($no_case) {
		$query .= "LIKE ";
		$wc = '%';
	} else {
		$query .= "GLOB ";
		$wc = '*';
	}
	$query .= "'" . $wc .  $q_str . $wc . "'";
	if ($source_only)
		$query .= " and type = 'S'";
	if ($db_tag)
		$query .= " and tag = '" . $db_tag . "'";
	$query .= " order by tag, package, type, pfile, sfile";
	p_debug("Query: %s\n", $query);
	$r = sqlite_query("$query", $s);
	if (sqlite_num_rows($r) >= 1) {
		if ($do_count) {
			if ($quiet) {
				printf("%d\n", sqlite_num_rows($r));
			} else {
				if ($db_tag) {
					printf("%d matche(s) in database for tag ($db_tag) and substring ($q_str)\n", sqlite_num_rows($r));
				} else {
					printf("%d matche(s) in database for substring ($q_str)\n", sqlite_num_rows($r));
				}
			}
			close_db($s);
			return;
		}
		$ltag = '';
		while ($row = sqlite_fetch_array($r, SQLITE_ASSOC)) {
			if (!$quiet)
				print("\n");
			if ($debug) {
    				print_r($row);
			} else {
				if ($ltag != $row[tag]) {
					$qtag = rq($row[tag]);
					$t = sqlite_query("select DISTINCT path from Tags where tag = $qtag", $s);
					$trow = sqlite_fetch_array($t, SQLITE_ASSOC);
					$path = $trow[path] . "/";
				}
				$src_rpm = $path . $row[package] . "-" . $row[version] . "-" . $row[release] . ".src.rpm";
				$stype = "Source";
				if ($src_rpm != $lsrc) {
					if (!$hide_tag)
						printf("%-5s%-10s Path:", "Tag:", $row[tag]);
					printf("%s\n", $src_rpm);
				}
				if ($quiet)
					$lsrc = $src_rpm;
				if (!$quiet) {
					if ($row[type] == "P")
						$stype = "Patch";
					if ($extra_info) {
						printf("%-16s%-27s%-9s%s\n", "Package:", $row[package], "Date:", date("D M j G:i:s T Y", $row[pdate]));
						printf("%-16s%-27s%-9s%s\n", "Version:", $row[version], "Release:", $row[release]);	
					}
					printf("%-16s%-27s%-9s%s\n", "Source File:", $row[pfile], "Type:", $stype);
					printf("%-16s%-30s\n", "Source Path:", $row[sfile]);
				}
			}
			$ltag = $row[tag];
		}
	} else {
		if ($db_tag) {
			perror("No matches in database for tag ($db_tag) and substring ($q_str) ...\n");
		} else {
			perror("No matches in database for substring ($q_str) ...\n");
		}
	}
	close_db($s);
}

function rpm_list($fname) {
	global $verbose, $update_db;
	$qcmd = "qlp";
	if ($verbose && !$update_db)
		$qcmd = "qlvp";
	$list = `rpm -$qcmd --nosignature $fname`;
	return $list;
}

function tar_list($fname) {
	$comp = 'tjf';
	if (eregi("tar.gz$", $fname)) 
		$comp = "tzf";
	if (eregi("tar$", $fname))
		$comp = "tf";
	$list = `tar -$comp $fname`;
	return $list;
}

function patch_list($fname) {
	global $verbose, $update_db;
	$grep = "bzgrep";
	if (eregi("patch.gz$", $fname)) 
		$grep = "zgrep";
	if (eregi("patch$", $fname))
		$grep = "grep";
	if ($verbose && !$update_db) {
		$list = `$grep '+++' $fname | sed 's|^+++ ||g'`;
	} else {
		$list = `$grep '+++' $fname | awk '{print $2}'`;
	}
	return $list;
}

function check_file($src_file) {
	if (!file_exists($src_file)) {
		printf("File %s not found\n", $src_file);
		exit(1);
	}
	if (!eregi("src.rpm$", $src_file)) {
		printf("File %s not a src.rpm\n", $src_file);
		exit(1);
	}
}

function verbose_name($fname) {
	// fname is messy is this case
	$flist = preg_split("/[\s]+/", $fname);
	return $flist[8];
}

function make_tmp_dir() {
	global $debug;
	// setup tmp dir
	$cpio_dir = tmp_dir("~/tmp", "srpm");
	if (!$cpio_dir) {
		printf("Can't create temporary dir for cpio\n");
		exit(1);
	}
	if ($debug)
		printf("Creating tmp dir %s\n", $cpio_dir);

	chdir($cpio_dir);
	return $cpio_dir;
}

function clean_tmp_dir($cpio_dir) {
	global $debug;
	if ($debug)
		printf("Cleaning tmp dir %s\n", $cpio_dir);

	foreach (glob("$cpio_dir/*") as $fname) {
		if (!unlink($fname))
		printf("Error removing file %s\n", $fname);
	}
	if (!rmdir($cpio_dir)) {
		printf("Error removing directory %s\n", $cpio_dir);
		exit(1);
	}	
}

function get_tar_files($srpm) {
	system("rpm2cpio $srpm | cpio -i --quiet *.tar.?z*");
}

function get_patch_files($srpm) {
	system("rpm2cpio $srpm | cpio -i --quiet *patch*");
}

function get_all_files($srpm) {
	get_tar_files($srpm);
	get_patch_files($srpm);
}

function fix_path($src_file, $cur_dir) {
	// if the path is relative, fix it
	$lslash = strpos($src_file, "/");
	if ($lslash === FALSE || $lslash > 0)
		$src_file = $cur_dir . "/" . $src_file;
	return $src_file;
}

function dump_file($src_file) {
	global $skip_tar, $show_patch, $verbose;
	$cur_dir = getcwd();
	$src_file = fix_path($src_file, $cur_dir);
	p_debug("File:\t%s\n", $src_file);
	check_file($src_file);

	// stage1 - list the rpm contents
	$src_list = rpm_list($src_file);
	printf("Contents:\n%s\n", $src_list);

	$cpio_dir = make_tmp_dir();
	$files = spliti("\n", $src_list);

	// stage2 - list patched files
	if ($show_patch) {
		get_patch_files($src_file);
		foreach ($files as $pfile) {
			if ($verbose)
				$pfile = verbose_name($pfile);
			if (eregi("patch.bz2$|patch.gz$|patch$", $pfile)) {
				$plist = patch_list($pfile);
				printf("Patch file %s modifies:\n%s\n", $pfile, $plist);
			}
		}
	}

	// stage3 - list the tarball contents

	if (!$skip_tar) {
		get_tar_files($src_file);
		foreach ($files as $tfile) {
			if ($verbose)
				$tfile = verbose_name($tfile);
			if (eregi("tar.bz2$|tar.gz$|tar$", $tfile)) {
				$tlist = tar_list($tfile);
				printf("Tarfile %s contents:\n%s\n", $tfile, $tlist);
			}
		}
	}

	// clean up our tmpdir stuff
	chdir($cur_dir);
	clean_tmp_dir($cpio_dir);
}

function tmp_dir($path, $prefix)
{
	// Use PHP's tmpfile function to create a temporary
	// directory name. Delete the file and keep the name.
	$tempname = tempnam($path,$prefix);
	if (!$tempname)
		return FALSE;

	if (!unlink($tempname))
		return FALSE;

	// Create the temporary directory and returns its name.
	if (mkdir($tempname))
		return $tempname;

	return FALSE;
}

// *************************************************************************************
// main program execution
// *************************************************************************************

// parse the arguments;
$self = $GLOBALS['argv'][0];
$opt = getopt("CdehiIlpPQrsSTvVa:c:D:f:q:t:u:");
$flist = array();

// default to extra args like -f
if ($GLOBALS['argc'] > sizeof($opt)) {
	for ($i = sizeof($opt) + 1; $i < $GLOBALS['argc']; $i++) {
		if (!eregi("^-", $GLOBALS['argv'][$i]))
			array_push($flist, $GLOBALS['argv'][$i]); 
	}
}

// debugging
//print_r($flist);
//print_r($opt);

if (array_key_exists('I', $opt)) {
    $db_access = read_rcfile();
	//print_r($db_access);
	create_db();
	exit(0);
}

if (array_key_exists('l', $opt)) {
    list_tags();
}

if (array_key_exists('v', $opt)) {
    $verbose = TRUE;
	p_debug("Verbose output ...\n", NULL);
}

if (array_key_exists('P', $opt)) {
    $progress = TRUE;
	p_debug("Show progess ...\n", NULL);
}

if (array_key_exists('r', $opt)) {
    rebuild_database();
    exit(0);
}

if (array_key_exists('V', $opt)) {
    printf("srpm v$srpm_version, $src_date $copyright $author\n");
	exit(0);
}

if(($opt[c] == '' && $opt[D] == '' && $opt[f] == '' && $opt[q] == '' && $opt[t] == '' 
  && $opt[u] == '' && sizeof($flist) == 0) || array_key_exists('h', $opt)) { 
	print_help($self);
}

// bail on missing argument
foreach(array('a', 'c', 'D', 'f', 'q', 't') as $args) { 
	if(eregi("^-", $opt[$args])) {
		printf("Option -%s requires a valid argument\n", $args);
		exit(1);
	}
}

if (array_key_exists('d', $opt)) {
    $debug = TRUE;
}

if (array_key_exists('e', $opt)) {
    $extra_info = TRUE;
}

if (array_key_exists('i', $opt)) {
    $no_case = TRUE;
}

if (array_key_exists('C', $opt)) {
    $do_count = TRUE;
	p_debug("Show counts only ...\n", NULL);
}

if (array_key_exists('Q', $opt)) {
    $quiet = TRUE;
	p_debug("Quiet output ...\n", NULL);
}

if (array_key_exists('p', $opt)) {
	$show_patch = TRUE;
	p_debug("Show patched files ...\n", NULL);
}

if (array_key_exists('s', $opt)) {
	$skip_tar = TRUE;
	p_debug("Skip tar file extract...\n", NULL);
}

if (array_key_exists('S', $opt)) {
	$source_only = TRUE;
	p_debug("Query source files only...\n", NULL);
}

if (array_key_exists('t', $opt)) {
	$db_tag = $opt[t];
	p_debug("Tag:\t%s\n", $db_tag);
}

if (array_key_exists('T', $opt)) {
	$hide_tag = TRUE;
}

if (sizeof($flist) > 0 && array_key_exists('a', $opt)) {
	$update_db = TRUE;
	if(!$db_tag) {
		perror("Please specify a tag...\n");
		exit(1);
	}
	foreach ($flist as $fname) {
		$havetag = check_for_tag($db_tag, $fname);
		if (!$havetag)
			add_tag_path($db_tag, $fname);
		add_record($db_tag, $fname);
	}
	exit(0);
}

if (array_key_exists('c', $opt)) {
	$src_dir = $opt[c];
	p_debug("Dir: \t%s\n", $src_dir);
	if(!$db_tag) {
		perror("Please specify a tag...\n");
		exit(1);
	}
	add_source_directory($db_tag, $src_dir);
	exit(0);
}

if (array_key_exists('D', $opt)) {
	$db_tag = $opt[D];
	p_debug("Tag: \t%s\n", $db_tag);
	delete_tag_entries($db_tag);
	exit(0);
}

if (array_key_exists('u', $opt)) {
	$db_tag = $opt[u];
	p_debug("Tag: \t%s\n", $db_tag);
	update_tag_entries($db_tag);
	exit(0);
}

if (array_key_exists('q', $opt)) {
	$q_str = $opt[q];
	p_debug("Query: \t%s\n", $opt[q]);
	do_query($q_str);
	exit(0);
}

if (array_key_exists('f', $opt)) dump_file($opt[f]);

if (sizeof($flist) > 0 && !array_key_exists('f', $opt)) {
	foreach ($flist as $fname) {
		dump_file($fname);
	}
}

exit(0);
?>
