File:  [Public] / rpm2html / sql.c
Revision 1.17: download - view: text, annotated - select for diffs
Fri Sep 8 10:54:03 2000 UTC (23 years, 8 months ago) by veillard
Branches: MAIN
CVS tags: HEAD
getting distrib id on Package records, Daniel

/*
 * sql.c: front-end for MySQL database
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
/********
#include <rpm/rpmlib.h>
 ********/

#include <mysql/mysql.h>
#include <mysql/errmsg.h>
#include "rpm2html.h"
/********
#include "rpmdata.h"
 ********/
#include "sql.h"

#ifdef STANDALONE
static int rpm2htmlVerbose = 1;
#endif

/************************************************************************
 * 									*
 * 		Generic inititialisation/close of the DB		*
 * 									*
 ************************************************************************/

static MYSQL *sql = NULL;
static const char *myhost, *mybase, *myuser, *mypasswd;

int init_sql(const char *host, const char *base, const char *user, const char *passwd) {
    int attempts = 0;

    /*
     * Close the previous connection if any
     */
    if (sql != NULL) {
	close_sql();
	if (myhost != NULL) free((char *) myhost);
	myhost = NULL;
	if (mybase != NULL) free((char *) mybase);
	mybase = NULL;
	if (myuser != NULL) free((char *) myuser);
	myuser = NULL;
	if (mypasswd != NULL) free((char *) mypasswd);
	mypasswd = NULL;
    }

    if (host == NULL)
	host = getenv("MySQL_HOST");
    if (host == NULL)
	host = "localhost";
    if (base == NULL)
	base = getenv("MySQL_BASE");
    if (base == NULL)
	base = "rpmfind";
    if (passwd == NULL)
	passwd = getenv("MySQL_PASS");
    if (user == NULL)
	user = getenv("MySQL_USER");
    if (user == NULL)
	user = getenv("USER");
    if (user == NULL)
	user = getenv("USERNAME");
    if (user == NULL)
	user = getenv("LOGNAME");
    sql = mysql_init(NULL);
    if (mysql_errno(sql)) {
	fprintf(stderr, "mysql_init failed: %s\n", mysql_error(sql));
	return(-1);
    }
    for (attempts = 0; ;attempts ++) {
	mysql_real_connect(sql, host, user, passwd, base, 0, NULL, 0);
	if (mysql_errno(sql)) {
	    if (attempts >= 20) {
		fprintf(stderr,
			"mysql: connect as %s to %s on host %s  failed: %s\n",
		        user, base, host, mysql_error(sql));
	    return(-1);
	    }
	} else {
	    break;
	}
	sleep(15);
    }
    myhost = strdup(host);
    mybase = strdup(base);
    myuser = strdup(user);
    mypasswd = strdup(passwd);
    sql_check_tables();
    return(0);
}

int close_sql(void) {
    mysql_close(sql);
    if (mysql_errno(sql)) {
	fprintf(stderr, "mysql_close failed: %s\n", mysql_error(sql));
	return(-1);
    }
    sql = NULL;
    return(0);
}

int restart_sql(void) {
    int attempts = 0;

    /*
     * Close the previous connection if any
     */
    if (sql != NULL) {
	close_sql();
	sql = NULL;
    }

    sql = mysql_init(NULL);
    if (mysql_errno(sql)) {
	fprintf(stderr, "mysql_init failed: %s\n", mysql_error(sql));
	return(-1);
    }
    for (attempts = 0; ;attempts ++) {
	mysql_real_connect(sql, myhost, myuser, mypasswd, mybase, 0, NULL, 0);
	if (mysql_errno(sql)) {
	    if (attempts >= 20) {
		fprintf(stderr,
			"mysql: reconnect as %s to %s on host %s  failed: %s\n",
		        myuser, mybase, myhost, mysql_error(sql));
	    return(-1);
	    }
	} else {
	    break;
	}
	sleep(15);
    }
    sql_check_tables();
    return(0);
}

/*
 * Handle disconnects by doing a reconnect and a retry.
 */
int do_sql_query(const char *query, int len) {
    int res;

    if (sql == NULL) {
	res = restart_sql();
	if (res != 0)
	    return(res);
    }
    res = mysql_real_query(sql, query, len);
    if ((res == CR_SERVER_GONE_ERROR) || (CR_SERVER_LOST)) {
	res = restart_sql();
	if (res != 0)
	    return(res);
	res = mysql_real_query(sql, query, len);
    }
    return(res);
}

/************************************************************************
 * 									*
 * 		Generic functions to access the tables			*
 * 									*
 ************************************************************************/

#define MAX_QUERY 8000
#define SMALL_QUERY 500

int sql_update_id(const char *table, int id,
	          const char *field, const char *value) {
    MYSQL_RES *result;
    char query[MAX_QUERY];
    int nb_fields = 0;
    int left = MAX_QUERY - 1;
    int len;
    char *end;

    if ((table == NULL) ||
	(field == NULL) || (value == NULL))
	return(-1);

    len = snprintf(query, left, "UPDATE %s SET %s='", table, field);
    if (len < 0) {
	fprintf(stderr, "sql_update_id : %s(%d).%s overflow\n",
		table, id, field);
	return(-1);
    }
    end = &query[len];
    left -= len;
    len = strlen(value);
    if (len * 2 >= left) {
	fprintf(stderr, "sql_update_id : %s(%d).%s overflow\n",
		table, id, field);
	return(-1);
    }
    len = mysql_escape_string(end, value, len);
    left -= len;
    if (left <= 0) {
	fprintf(stderr, "sql_update_id : %s(%d).%s overflow\n",
		table, id, field);
	return(-1);
    }
    end += len;
    len = snprintf(end, left, "' WHERE ID=%d", id);
    if (len < 0) {
	fprintf(stderr, "sql_update_id : %s(%d).%s overflow\n",
		table, id, field);
	return(-1);
    }
    end += len;
    query[MAX_QUERY - 1] = 0;

    if (do_sql_query(query, (unsigned int) (end - query))) {
	printf("sql_update_id: UPDATE %s %d failed: %s\n",
	       table, id, mysql_error(sql));
	return(-1);
    }
    result = mysql_store_result(sql);
    if (result != NULL) {
	nb_fields = mysql_num_fields(result);
	mysql_free_result(result);
    } else {
	nb_fields = 1;
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "sql_update_id UPDATE error: %s\n",
		 mysql_error(sql));
	return(-1);
    }
    return(nb_fields);
}

int sql_blind_insert(const char *table, const char *key,
                     const char *value, int id) {
    MYSQL_RES *result;
    char query[MAX_QUERY];
    int left = MAX_QUERY - 1;
    int len;
    char *end;
    int insert = -1;

    if ((table == NULL) ||
	(key == NULL) || (value == NULL))
	return(-1);

    /*
     * Search first for the ID if it already exists
     */
    if (id > 0) {
	len = snprintf(query, left, "INSERT INTO %s (ID, %s) VALUES (%d, '",
		       table, key, id);
	if (len < 0) {
	    fprintf(stderr, "sql_blind_insert : %s(%d).%s overflow\n",
		    table, id, key);
	    return(-1);
	}
	end = &query[len];
	left -= len;
	len = strlen(value);
	if (len * 2 >= left) {
	    fprintf(stderr, "sql_blind_insert : %s(%d).%s overflow\n",
		    table, id, key);
	    return(-1);
	}
	len = mysql_escape_string(end, value, len);
	left -= len;
	if (left <= 0) {
	    fprintf(stderr, "sql_blind_insert : %s(%d).%s overflow\n",
		    table, id, key);
	    return(-1);
	}
	end += len;
	len = snprintf(end, left, "')");
	if (len < 0) {
	    fprintf(stderr, "sql_blind_insert : %s(%d).%s overflow\n",
		    table, id, key);
	    return(-1);
	}
	end += len;
	query[MAX_QUERY - 1] = 0;

    } else {
	len = snprintf(query, left, "INSERT INTO %s (%s) VALUES ('",
		       table, key);
	if (len < 0) {
	    fprintf(stderr, "sql_blind_insert : %s.%s overflow\n",
		    table, key);
	    return(-1);
	}
	end = &query[len];
	left -= len;
	len = strlen(value);
	if (len * 2 >= left) {
	    fprintf(stderr, "sql_blind_insert : %s.%s overflow\n",
		    table, key);
	    return(-1);
	}
	len = mysql_escape_string(end, value, len);
	left -= len;
	if (left <= 0) {
	    fprintf(stderr, "sql_blind_insert : %s.%s overflow\n",
		    table, key);
	    return(-1);
	}
	end += len;
	len = snprintf(end, left, "')");
	if (len < 0) {
	    fprintf(stderr, "sql_blind_insert : %s.%s overflow\n",
		    table, key);
	    return(-1);
	}
	end += len;
	query[MAX_QUERY - 1] = 0;

    }
    query[MAX_QUERY - 1] = 0;
    if (do_sql_query(query, (unsigned int) (end - query))) {
#ifdef SQL_DEBUG
	fprintf(stderr, "sql_blind_insert Error: %s\n", mysql_error(sql));
#endif
	return(-1);
    }
    result = mysql_store_result(sql);
    insert = mysql_insert_id(sql);
    if (result) {
	mysql_free_result(result);
	return(insert);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "sql_blind_insert Error: %s\n", mysql_error(sql));
	return(-1);
    }
    return(insert);
}

int sql_update(const char *table, const char *name,
	       const char *field, const char *value) {
    MYSQL_RES *result;
    MYSQL_ROW row;
    char query[MAX_QUERY];
    int id;
    int nb_fields = 0;
    int left = MAX_QUERY - 1;
    int len;
    char *end;

    if ((name == NULL) || (table == NULL) ||
	(field == NULL) || (value == NULL))
	return(-1);

    /*
     * Search first for the ID if it already exists
     */
    snprintf(query, MAX_QUERY - 1, "SELECT ID FROM %s WHERE Name='%s'", table, name);
    query[MAX_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_update: SELECT failed\n");
	return(-1);
    }

    result = mysql_use_result(sql);
    if (result) {
	while((row = mysql_fetch_row(result)))
	{
	    if (row[0] == NULL) {
		printf("sql_update: select ID for %s returns NULL !\n", name);
		return(-1);
	    }
	    if (sscanf(row[0], "%d", &id) != 1) {
		printf("sql_update: ID non numeric %s\n", row[0]);
		return(-1);
	    }

	    left = MAX_QUERY - 1;
	    len = snprintf(query, left, "UPDATE %s SET %s='", table, field);
	    if (len < 0) {
		fprintf(stderr, "sql_update : %s(%d).%s overflow\n",
			table, id, field);
		return(-1);
	    }
	    end = &query[len];
	    left -= len;
	    len = strlen(value);
	    if (len * 2 >= left) {
		fprintf(stderr, "sql_update : %s(%d).%s overflow\n",
			table, id, field);
		return(-1);
	    }
	    len = mysql_escape_string(end, value, len);
	    left -= len;
	    if (left <= 0) {
		fprintf(stderr, "sql_update : %s(%d).%s overflow\n",
			table, id, field);
		return(-1);
	    }
	    end += len;
	    len = snprintf(end, left, "' WHERE ID=%d", id);
	    if (len < 0) {
		fprintf(stderr, "sql_update : %s(%d).%s overflow\n",
			table, id, field);
		return(-1);
	    }
	    end += len;
	    query[MAX_QUERY - 1] = 0;

	    mysql_free_result(result);
	    if (do_sql_query(query, (unsigned int) (end - query))) {
		printf("sql_update: UPDATE failed: %s\n", mysql_error(sql));
		return(-1);
	    }
	    result = mysql_store_result(sql);
	    if (result != NULL) {
		nb_fields = mysql_num_fields(result);
		mysql_free_result(result);
	    } else {
		return(1);
	    }
	    /* Do not loop ... only the first */
	    return(nb_fields);
	}
	mysql_free_result(result);
	if (nb_fields == 0) {
	    /*
	     * Propagate an insert
	     */
	    snprintf(query, MAX_QUERY - 1,
		    "INSERT INTO %s (Name,%s) VALUES ('%s','%s')",
		     table, field, name, value);
	    query[MAX_QUERY - 1] = 0;
	    mysql_free_result(result);
	    if (mysql_query(sql, query)) {
		printf("sql_update: INSERT failed: %s\n", mysql_error(sql));
		return(-1);
	    }
	    result = mysql_store_result(sql);
	    if (result != NULL) {
		nb_fields = mysql_num_fields(result);
		mysql_free_result(result);
	    } else {
		return(1);
	    }
	}
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "sql_update Error: %s\n", mysql_error(sql));
	return(-1);
    }
    return(nb_fields);
}

int sql_get_key(const char *table, const char *name, const char *value) {
    int id;
    MYSQL_RES *result;
    MYSQL_ROW row;
    char query[SMALL_QUERY];

    if ((table == NULL) || (name == NULL))
	return(-1);

    /*
     * Search first for the ID if it already exists
     */
    snprintf(query, SMALL_QUERY - 1, "SELECT ID FROM %s WHERE %s='%s'",
	     table, name, value);
    query[SMALL_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_create: SELECT %s failed %s\n", name, mysql_error(sql));
	return(-1);
    }

    result = mysql_use_result(sql);
    if (result) {
	while((row = mysql_fetch_row(result)))
	{
	    /*
	     * Lookup the first ID and return it
	     */
	    if (row[0] == NULL) {
		mysql_free_result(result);
		printf("sql_create: select returns NULL !\n");
		return(-1);
	    }
	    if (sscanf(row[0], "%d", &id) != 1) {
		mysql_free_result(result);
		printf("sql_create: ID non numeric %s\n", row[0]);
		return(-1);
	    }
	    mysql_free_result(result);
	    return(id);
	}
	mysql_free_result(result);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
	return(-1);
    }

    /*
     * Do a creation
     */

    snprintf(query, SMALL_QUERY - 1, "INSERT INTO %s (%s) VALUES ('%s')",
	     table, name, value);
    query[SMALL_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_get_key: INSERT %s failed %s\n", name, mysql_error(sql));
	return(-1);
    }
    id = mysql_insert_id(sql);
    result = mysql_store_result(sql);
    if (result != NULL)
	mysql_free_result(result);
    return(id);
}

int sql_read_key(const char *table, const char *name) {
    int id;
    MYSQL_RES *result;
    MYSQL_ROW row;
    char query[SMALL_QUERY];

    if ((table == NULL) || (name == NULL))
	return(-1);

    /*
     * Search for the ID it has to exist
     */
    snprintf(query, SMALL_QUERY - 1, "SELECT ID FROM %s WHERE Name='%s'", table, name);
    query[SMALL_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_create: SELECT %s failed %s\n", name, mysql_error(sql));
	return(-1);
    }

    result = mysql_use_result(sql);
    if (result) {
	while((row = mysql_fetch_row(result)))
	{
	    /*
	     * Lookup the first ID and return it
	     */
	    if (row[0] == NULL) {
		mysql_free_result(result);
		printf("sql_create: select returns NULL !\n");
		return(-1);
	    }
	    if (sscanf(row[0], "%d", &id) != 1) {
		mysql_free_result(result);
		printf("sql_create: ID non numeric %s\n", row[0]);
		return(-1);
	    }
	    mysql_free_result(result);
	    return(id);
	}
	mysql_free_result(result);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
	return(-1);
    }
    return(-1);
}

int sql_read_info_key(const char *table, const char *name, const char *value) {
    int id;
    MYSQL_RES *result;
    MYSQL_ROW row;
    char query[SMALL_QUERY];

    if ((table == NULL) || (name == NULL) || (value == NULL))
	return(-1);

    /*
     * Search for the ID it has to exist
     */
    snprintf(query, SMALL_QUERY - 1, "SELECT ID FROM %s WHERE %s='%s'", table, name, value);
    query[SMALL_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_create: SELECT %s failed %s\n", name, mysql_error(sql));
	return(-1);
    }

    result = mysql_use_result(sql);
    if (result) {
	while((row = mysql_fetch_row(result)))
	{
	    /*
	     * Lookup the first ID and return it
	     */
	    if (row[0] == NULL) {
		mysql_free_result(result);
		printf("sql_create: select returns NULL !\n");
		return(-1);
	    }
	    if (sscanf(row[0], "%d", &id) != 1) {
		mysql_free_result(result);
		printf("sql_create: ID non numeric %s\n", row[0]);
		return(-1);
	    }
	    mysql_free_result(result);
	    return(id);
	}
	mysql_free_result(result);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
	return(-1);
    }
    return(-1);
}

/************************************************************************
 *									*
 *				Tables handling				*
 *									*
 ************************************************************************/

int sql_rebuild_config(void) {
    const char *query =
"CREATE TABLE Config ( \n\
    ID int(11) NOT NULL auto_increment, \n\
    Name varchar(50) NOT NULL, \n\
    Value varchar(255), \n\
    PRIMARY KEY (ID), \n\
    KEY Name (Name(10)) \n\
)";

    if (mysql_query(sql,query)) {
	printf("sql_rebuild_config: CREATE TABLE Config failed %s\n",
	       mysql_error(sql));
	return(-1);
    }
    return(0);
}

int sql_rebuild_vendors(void) {
    const char *query =
"CREATE TABLE Vendors ( \n\
    ID int(11) NOT NULL auto_increment, \n\
    Name varchar(255) NOT NULL, \n\
    URL varchar(255), \n\
    Key1 text, \n\
    Key2 text, \n\
    Key3 text, \n\
    Description text, \n\
    PRIMARY KEY (ID), \n\
    KEY Name (Name(10)) \n\
)";

    if (mysql_query(sql,query)) {
	printf("sql_rebuild_vendors: CREATE TABLE Vendors failed %s\n",
	       mysql_error(sql));
	return(-1);
    }
    return(0);
}

int sql_rebuild_mirrors(void) {
    const char *query =
"CREATE TABLE Mirrors ( \n\
    ID int(11), \n\
    URL varchar(255) NOT NULL, \n\
    Country int(11), \n\
    UNIQUE(URL) \n\
)";

    if (mysql_query(sql,query)) {
	printf("sql_rebuild_mirrors: CREATE TABLE Mirrors failed %s\n",
	       mysql_error(sql));
	return(-1);
    }
    return(0);
}

int sql_rebuild_metadata(void) {
    const char *query =
"CREATE TABLE Metadata ( \n\
    URL varchar(255) NOT NULL, \n\
    Maintainer int(11), \n\
    Country int(11), \n\
    UNIQUE(URL) \n\
)";

    if (mysql_query(sql,query)) {
	printf("sql_rebuild_metadata: CREATE TABLE Metadata failed %s\n",
	       mysql_error(sql));
	return(-1);
    }
    return(0);
}

int sql_rebuild_distribs(void) {
    const char *query =
"CREATE TABLE Distribs ( \n\
    ID int(11) NOT NULL auto_increment, \n\
    Name varchar(255) NOT NULL, \n\
    Vendor int(11), \n\
    Directory varchar(255), \n\
    Path varchar(100) NOT NULL, \n\
    URL varchar(255), \n\
    URLSrc varchar(255), \n\
    Html varchar(8), \n\
    Color varchar(10), \n\
    Key1 text, \n\
    Key2 text, \n\
    Description text, \n\
    PRIMARY KEY (ID), \n\
    KEY Name (Name(10)) \n\
)";

    if (mysql_query(sql,query)) {
	printf("sql_rebuild_distribs: CREATE TABLE Distribs failed %s\n",
	       mysql_error(sql));
	return(-1);
    }
    return(0);
}

int sql_rebuild_packages(void) {
    const char *query =
"CREATE TABLE Packages ( \n\
ID int(11) NOT NULL auto_increment, \n\
filename varchar(255) NOT NULL, \n\
Name varchar(50) NOT NULL, \n\
Version varchar(50) NOT NULL, \n\
Release varchar(50) NOT NULL, \n\
Arch varchar(15) NOT NULL, \n\
Dist int(11), \n\
URL varchar(255), \n\
URLSrc varchar(255), \n\
Vendor int(11), \n\
Packager int(11), \n\
Category varchar(255), \n\
Summary varchar(255), \n\
Description text, \n\
Copyright varchar(255), \n\
PRIMARY KEY (ID), \n\
KEY filename (filename(80)), \n\
KEY Name (Name(15)) \n\
)";

    if (mysql_query(sql,query)) {
	printf("sql_rebuild_packages: CREATE TABLE Packages failed %s\n",
	       mysql_error(sql));
	return(-1);
    }
    return(0);
}

int sql_rebuild_files(void) {
    const char *query =
"CREATE TABLE Files ( \n\
    ID int(11) NOT NULL, \n\
    Path varchar(35) NOT NULL, \n\
    UNIQUE KEY id (ID,Path(35)), \n\
    INDEX (ID), \n\
    INDEX (Path) \n\
)";

    if (mysql_query(sql,query)) {
	printf("sql_rebuild_files: CREATE TABLE Files failed %s\n",
	       mysql_error(sql));
	return(-1);
    }
    return(0);
}

int sql_rebuild_provides(void) {
    const char *query =
"CREATE TABLE Provides ( \n\
    ID int(11) NOT NULL, \n\
    Resource varchar(35) NOT NULL, \n\
    UNIQUE KEY id (ID,Resource(35)), \n\
    INDEX (ID), \n\
    INDEX (Resource) \n\
)";

    if (mysql_query(sql,query)) {
	printf("sql_rebuild_files: CREATE TABLE Provides failed %s\n",
	       mysql_error(sql));
	return(-1);
    }
    return(0);
}

int sql_rebuild_requires(void) {
    const char *query =
"CREATE TABLE Requires ( \n\
    ID int(11) NOT NULL, \n\
    Resource varchar(35) NOT NULL, \n\
    Rel char(2), \n\
    Value varchar(20), \n\
    UNIQUE KEY id (ID,Resource(35)), \n\
    INDEX (ID), \n\
    INDEX (Resource) \n\
)";

    if (mysql_query(sql,query)) {
	printf("sql_rebuild_files: CREATE TABLE Requires failed %s\n",
	       mysql_error(sql));
	return(-1);
    }
    return(0);
}


int sql_check_tables(void) {
    const char *query = "SHOW TABLES";
    MYSQL_RES *result;
    MYSQL_ROW row;
    int config = 0;
    int distribs = 0;
    int requires = 0;
    int provides = 0;
    int vendors = 0;
    int mirrors = 0;
    int metadata = 0;
    int packages = 0;
    int files = 0;

    int rebuilt = 0;

    if (mysql_query(sql,query)) {
	printf("sql_check_tables: SHOW TABLES failed %s\n",
	       mysql_error(sql));
	return(-1);
    }

    result = mysql_use_result(sql);
    if (result) {
	while((row = mysql_fetch_row(result)))
	{
	    if (row[0] == NULL) {
		mysql_free_result(result);
		printf("sql_check_tables: SHOW TABLES returns NULL !\n");
		return(-1);
	    }
	    if (!strcmp(row[0], "Config"))
		config = 1;
	    if (!strcmp(row[0], "Distribs"))
		distribs = 1;
	    if (!strcmp(row[0], "Vendors"))
		vendors = 1;
	    if (!strcmp(row[0], "Mirrors"))
		mirrors = 1;
	    if (!strcmp(row[0], "Metadata"))
		metadata = 1;
	    if (!strcmp(row[0], "Packages"))
		packages = 1;
	    if (!strcmp(row[0], "Files"))
		files = 1;
	    if (!strcmp(row[0], "Requires"))
		requires = 1;
	    if (!strcmp(row[0], "Provides"))
		provides = 1;
	}
	mysql_free_result(result);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
	return(-1);
    }

    if (!config) {
	fprintf(stderr, "Table Config disapeared: rebuilding it\n");
	if (!sql_rebuild_config())
	    rebuilt++;
    }
    if (!vendors) {
	fprintf(stderr, "Table Vendors disapeared: rebuilding it\n");
	if (!sql_rebuild_vendors())
	    rebuilt++;
    }
    if (!distribs) {
	fprintf(stderr, "Table Distribs disapeared: rebuilding it\n");
	if (!sql_rebuild_distribs())
	    rebuilt++;
    }
    if (!mirrors) {
	fprintf(stderr, "Table Mirrors disapeared: rebuilding it\n");
	if (!sql_rebuild_mirrors())
	    rebuilt++;
    }
    if (!metadata) {
	fprintf(stderr, "Table Metadata disapeared: rebuilding it\n");
	if (!sql_rebuild_metadata())
	    rebuilt++;
    }
    if (!packages) {
	fprintf(stderr, "Table Packages disapeared: rebuilding it\n");
	if (!sql_rebuild_packages())
	    rebuilt++;
    }
    if (!files) {
	fprintf(stderr, "Table Files disapeared: rebuilding it\n");
	if (!sql_rebuild_files())
	    rebuilt++;
    }
    if (!requires) {
	fprintf(stderr, "Table Requires disapeared: rebuilding it\n");
	if (!sql_rebuild_requires())
	    rebuilt++;
    }
    if (!provides) {
	fprintf(stderr, "Table Provides disapeared: rebuilding it\n");
	if (!sql_rebuild_provides())
	    rebuilt++;
    }
    return(rebuilt);
}

/************************************************************************
 *									*
 *			Specific rpm2html functions			*
 *									*
 ************************************************************************/

int sql_add_dist_mirror(int distrib, const char *URL, int country) {
    if (URL == NULL)
	return(-1);
    if (distrib < 0)
	return(-1);
    return(sql_blind_insert("Mirrors", "URL", URL, distrib));
}

int sql_add_mirror(const char *Name, const char *URL, int country) {
    int distrib;

    if ((Name == NULL) || (URL == NULL))
	return(-1);
    distrib = sql_read_key("Distribs", Name);
    if (distrib < 0)
	return(distrib);
    return(sql_blind_insert("Mirrors", "URL", URL, distrib));
}

int sql_add_file(const char *filename, int package) {
    if ((filename == NULL) || (package <= 0))
	return(-1);
    if (strlen(filename) > 35)
	return(0);

    return(sql_blind_insert("Files", "Path", filename, package));
}

int sql_add_provides(int package, const char *resource) {
    if ((resource == NULL) || (package <= 0))
	return(-1);
    if (strlen(resource) > 35)
	return(0);

    return(sql_blind_insert("Provides", "Resource", resource, package));
}

int sql_add_requires(int package, const char *resource, rpm_dep_flag rel,
	             const char *value) {
    int record;
    if ((resource == NULL) || (package <= 0))
	return(-1);
    if (strlen(resource) > 35)
	return(0);

    record = sql_blind_insert("Requires", "Resource", resource, package);
    if ((rel != RPM2HTML_REQ_NONE) && (value != NULL) &&
	(strlen(value) <= 50)) {
	char query[SMALL_QUERY];

	switch (rel) {
	    case RPM2HTML_REQ_LT:
		snprintf(query, SMALL_QUERY - 1,
			 "UPDATE Requires SET Rel='<',Value='%s' WHERE ID=%d",
			 value, record);
	        break;
	    case RPM2HTML_REQ_LEQ:
		snprintf(query, SMALL_QUERY - 1,
			 "UPDATE Requires SET Rel='<=',Value='%s' WHERE ID=%d",
			 value, record);
	        break;
	    case RPM2HTML_REQ_GT:
		snprintf(query, SMALL_QUERY - 1,
			 "UPDATE Requires SET Rel='>',Value='%s' WHERE ID=%d",
			 value, record);
	        break;
	    case RPM2HTML_REQ_GEQ:
		snprintf(query, SMALL_QUERY - 1,
			 "UPDATE Requires SET Rel='>=',Value='%s' WHERE ID=%d",
			 value, record);
	        break;
	    case RPM2HTML_REQ_EQU:
		snprintf(query, SMALL_QUERY - 1,
			 "UPDATE Requires SET Rel='=',Value='%s' WHERE ID=%d",
			 value, record);
	        break;
	    case RPM2HTML_REQ_NONE:
		query[0] = 0;
	}
	query[SMALL_QUERY - 1] = 0;
	if (mysql_query(sql,query)) {
	    printf("sql_create: UPDATE Requires %d failed %s\n",
		   record, mysql_error(sql));
	    return(record);
	}
    }
    return(record);
}

int sql_add_package(const char *filename,
	const char *Name, const char *Version, const char *Release,
	const char *Arch,
	int dist, const char *URL, const char *URLSrc, int vendor,
	const char *Packager, const char *Category, const char *Summary,
	const char *Description, const char *Copyright) {
    int id;
    /* int packager;
    char intStr[15]; */
    int nb_fields = 0;

    if (filename == NULL)
	return(-1);

    if (dist < 0)
	return(-1);
    if ((Name == NULL) || (Version == NULL) || (Release == NULL) ||
	(Arch == NULL))
	return(-1);

    id = sql_get_key("Packages", "filename", filename);
    if (id <= 0)
	return(-1);
    nb_fields = 1;

    if (rpm2htmlVerbose > 1)
	printf("Adding %s ID %d\n", filename, id);

    /*******
    if (Packager != NULL) {
	packager = sql_get_key("People", Packager);
	sprintf(intStr, "%d", packager);
	nb_fields += sql_update_id("Distribs", id, "Packager", intStr);
    }
     *******/
    if (Name != NULL)
	nb_fields += sql_update_id("Packages", id, "Name", Name);
    if (Version != NULL)
	nb_fields += sql_update_id("Packages", id, "Version", Version);
    if (Release != NULL)
	nb_fields += sql_update_id("Packages", id, "Release", Release);
    if (Release != NULL)
	nb_fields += sql_update_id("Packages", id, "Arch", Arch);
    if (Category != NULL)
	nb_fields += sql_update_id("Packages", id, "Category", Category);
    if (URL != NULL)
	nb_fields += sql_update_id("Packages", id, "URL", URL);
    if (URLSrc != NULL)
	nb_fields += sql_update_id("Packages", id, "URLSrc", URLSrc);
    if (dist >= 0) {
	char str[30];
	snprintf(str, 30, "%d", dist);
	str[29] = 0;
	nb_fields += sql_update_id("Packages", id, "Dist", str);
    }
    if (Summary != NULL)
	nb_fields += sql_update_id("Packages", id, "Summary", Summary);
    if (Description != NULL)
	nb_fields += sql_update_id("Packages", id,
				   "Description", Description);
    if (Copyright != NULL)
	nb_fields += sql_update_id("Packages", id, "Copyright", Copyright);
    
    return(id);
}

int sql_get_distrib_by_name(const char *Name) {
    int ret;

    if (Name == NULL)
	return(-1);
    ret = sql_read_key("Distribs", Name);

fprintf(stderr, "sql_get_distrib_by_name(%s) => %d\n", Name, ret);

    return(ret);
}

int sql_get_distrib_by_directory(const char *Directory) {
    int ret;

    if (Directory == NULL)
	return(-1);

    ret = sql_get_key("Distribs", "Directory", Directory);

fprintf(stderr, "sql_get_distrib_by_directory(%s) => %d\n", Directory, ret);

    return(ret);
}

int sql_add_distrib(const char *Name, const char *Vendor,
	const char *Directory, const char *Path, const char *URL,
	const char *URLSrc, const char *Description,
	const char *Html, const char *Color) {
    int id, vendor;
    int nb_fields = 0;
    char VendorStr[15];

    if (Name == NULL)
	return(-1);

    id = sql_get_key("Distribs", "Name", Name);
    nb_fields = 1;
    if (Vendor != NULL) {
	vendor = sql_get_key("Vendors", "Name", Vendor);
	sprintf(VendorStr, "%d", vendor);
	nb_fields += sql_update_id("Distribs", id, "Vendor", VendorStr);
    }
    if (Directory != NULL)
	nb_fields += sql_update_id("Distribs", id, "Directory", Directory);
    if (Path != NULL)
	nb_fields += sql_update_id("Distribs", id, "Path", Path);
    if (URL != NULL)
	nb_fields += sql_update_id("Distribs", id, "URL", URL);
    if (URLSrc != NULL)
	nb_fields += sql_update_id("Distribs", id, "URLSrc", URLSrc);
    if (Html != NULL)
	nb_fields += sql_update_id("Distribs", id, "Html", Html);
    if (Color != NULL)
	nb_fields += sql_update_id("Distribs", id, "Color", Color);
    if (Description != NULL)
	nb_fields += sql_update_id("Distribs", id,
				   "Description", Description);
    
    return(nb_fields);
}

int sql_add_vendor(const char *Name, const char *URL, const char *Description) {
    int id;
    int nb_fields = 0;

    if (Name == NULL)
	return(-1);

    id = sql_get_key("Vendors", "Name", Name);
    nb_fields = 1;
    if (URL != NULL)
	nb_fields += sql_update_id("Vendors", id, "URL", URL);
    if (Description != NULL)
	nb_fields += sql_update_id("Vendors", id,
				   "Description", Description);
    
    return(nb_fields);
}

void sql_add_config_info(const char *name, const char *value) {
    sql_update("Config", name, "Value", value);
}

void sql_add_metadata_base(const char *URL) {
    sql_blind_insert("Metadata", "URL", URL, -1);
}

/************************************************************************
 * 									*
 * 			Cleanup functions				*
 * 									*
 ************************************************************************/

int sql_remove_package(int id) {
    char query[SMALL_QUERY];

    if (id <= 0)
	return(-1);

    /*
     * remove the ID from the package list
     */
    snprintf(query, SMALL_QUERY - 1, "DELETE FROM Packages WHERE ID=%d", id);
    query[SMALL_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_create: DELETE package %d failed %s\n", id, mysql_error(sql));
	return(-1);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
	return(-1);
    }

    /*
     * remove the associated files from the Files list
     */
    snprintf(query, SMALL_QUERY - 1, "DELETE FROM Files WHERE ID=%d", id);
    query[SMALL_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_create: DELETE Files %d failed %s\n", id, mysql_error(sql));
	return(-1);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
	return(-1);
    }

    /*
     * remove the associated Provides entries
     */
    snprintf(query, SMALL_QUERY - 1, "DELETE FROM Provides WHERE ID=%d", id);
    query[SMALL_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_create: DELETE Provides %d failed %s\n", id, mysql_error(sql));
	return(-1);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
	return(-1);
    }

    /*
     * remove the associated Requires entries
     */
    snprintf(query, SMALL_QUERY - 1, "DELETE FROM Requires WHERE ID=%d", id);
    query[SMALL_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_create: DELETE Requires %d failed %s\n", id, mysql_error(sql));
	return(-1);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
	return(-1);
    }

    return(-1);
}

int sql_check_packages(void) {
    MYSQL_RES *result;
    MYSQL_ROW row;
    char *query = "SELECT filename,ID FROM Packages LIMIT 500";
    struct stat buf;
    int id;
    int ids[500];
    int index;
    int total = 0;

    if (rpm2htmlVerbose)
	printf("Database cleanup\n");
rescan:
    index = 0;
    /*
     * Search first for the ID if it already exists
     */
    if (mysql_query(sql,query)) {
	printf("sql_check_packages: SELECT from Packages failed: %s\n",
	       mysql_error(sql));
	return(-1);
    }

    result = mysql_use_result(sql);
    if (result) {
	while((row = mysql_fetch_row(result)))
	{
	    if ((row[0] == NULL) || (row[1] == NULL)) {
		printf("sql_check_packages: Path or ID is NULL !\n");
		continue;
	    }
	    if ((stat(row[0], &buf) < 0) || (buf.st_size < 50)) {
		/*
		 * Need to remove the package from the database.
		 */
		if (sscanf(row[1], "%d", &id) != 1) {
		    printf("sql_check_packages: ID non numeric %s\n", row[1]);
		    continue;
		}
		ids[index++] = id;
		if (rpm2htmlVerbose > 1)
		    printf("Removing %s ID %d\n", row[0], id);
		if (index >= 500)
		    break;
	    }
	}
	mysql_free_result(result);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "sql_update Error: %s\n", mysql_error(sql));
	return(-1);
    }

    /*
     * Do the cleanup.
     */
    for (id = 0;id < index;id++) {
	sql_remove_package(ids[id]);
    }

    total += index;
    if (index >= 500)
	goto rescan;
    if (rpm2htmlVerbose)
	printf("Database cleanup : removed %d entries\n", total);
    return(total);
}

/************************************************************************
 * 									*
 * 			Export functions				*
 * 									*
 ************************************************************************/

void sql_show_config(void) {
    MYSQL_RES *result;
    MYSQL_ROW row;
    int id, i;
    int index = 0;
    int ids[500];
    char query[SMALL_QUERY];


    printf(";\n; Configuration file for rpm2html\n");
    printf("; http://rpmfind.net/linux/rpm2html/\n;\n\n");
    mysql_query(sql,"SELECT Name,Value FROM Config");
    result = mysql_use_result(sql);

    while((row = mysql_fetch_row(result)))
    {
	if (row[0] == NULL) {
	    printf("\n");
	} else {
	    if (!strcmp(row[0], "maint"))
		printf("; maintainer of the local rpm mirror\n");
	    else if (!strcmp(row[0], "mail"))
		printf("; mail for the maintainer\n");
	    else if (!strcmp(row[0], "dir"))
                printf("; Directory to store the HTML pages produced\n");
	    else if (!strcmp(row[0], "url"))
                printf("; The relative URL for front pages\n");
	    else if (!strcmp(row[0], "header"))
                printf("; Extra link in the navigation bar\n");
	    else if (!strcmp(row[0], "html"))
                printf("; Export the local packages in HTML format\n");
	    else if (!strcmp(row[0], "tree"))
                printf("; Build the tree for the distributions\n");
	    else if (!strcmp(row[0], "rdf"))
                printf("; Export the local packages in RDF format\n");
	    else if (!strcmp(row[0], "rdf_dir"))
                printf("; Directory to store the RDf tree\n");
	    else if (!strcmp(row[0], "rdf_resources"))
                printf("; Compile a list of resources in RDF format\n");
	    else if (!strcmp(row[0], "rdf_resources_dir"))
                printf("; Directory to store the RDf resources tree\n");

	    if (row[1] == NULL)
		printf("%s\n\n", row[0]);
	    else
		printf("%s=%s\n\n", row[0], row[1]);
	}
    }
    mysql_free_result(result);
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
    }

    /*
     * Dump the Metadata
     */
    printf(";\n; The metadata mirrors list\n;\n\n[metadata]\n");
    mysql_query(sql,"SELECT URL FROM Metadata");
    result = mysql_use_result(sql);

    while((row = mysql_fetch_row(result)))
    {
	if (row[0] != NULL) {
	    printf("mirror=%s\n", row[0]);
	}
    }
    mysql_free_result(result);
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
    }

    /*
     * Dump the distributions informations
     * 1/ collect the list of IDs for the distribs
     */
    printf("\n\n;\n; The distribution list\n;\n\n");
    mysql_query(sql,"SELECT ID FROM Distribs");
    result = mysql_use_result(sql);

    while((row = mysql_fetch_row(result)))
    {
	if (row[0] != NULL) {
	    if (sscanf(row[0], "%d", &id) == 1) {
		ids[index++] = id;
	    }
	}
    }
    mysql_free_result(result);

    /*
     * Dump each distribution separately.
     */
    for (i = 0;i < index;i++) {

	snprintf(query, SMALL_QUERY - 1,
 "SELECT Directory,Name,Vendor,Path,URL,URLSrc,Description,Html,Color \
		  FROM Distribs WHERE ID=%d", ids[i]);
	query[SMALL_QUERY - 1] = 0;
	if (mysql_query(sql,query)) {
	    printf("sql_show_config: SELECT Distrib %d failed: %s\n",
		   ids[i], mysql_error(sql));
	    continue;
	}

	result = mysql_use_result(sql);
	if (result) {
	    while((row = mysql_fetch_row(result)))
	    {
		if (row[0] == NULL)
		    break;
		printf("[%s]\n", row[0]);
		if (row[1] != NULL)
		    printf("name=%s\n", row[1]);
		if (row[3] != NULL)
		    printf("subdir=%s\n", row[3]);
		if (row[4] != NULL)
		    printf("ftp=%s\n", row[4]);
		if (row[5] != NULL)
		    printf("ftpsrc=%s\n", row[5]);
		if (row[7] != NULL)
		    printf("html=%s\n", row[7]);
		if (row[8] != NULL)
		    printf("color=%s\n", row[8]);
	    }
	}
	mysql_free_result(result);

	/*
	 * Extract the mirrors for this distribution.
	 */
	snprintf(query, SMALL_QUERY - 1,
		 "SELECT URL FROM Mirrors WHERE ID=%d", ids[i]);
	query[SMALL_QUERY - 1] = 0;
	if (mysql_query(sql,query)) {
	    printf("sql_show_config: SELECT Mirrors %d failed: %s\n",
		   ids[i], mysql_error(sql));
	    printf("\n\n");
	    continue;
	}
	result = mysql_use_result(sql);
	if (result) {
	    while((row = mysql_fetch_row(result)))
	    {
		if (row[0] == NULL)
		    continue;
		printf("mirror=%s\n", row[0]);
	    }
	}
	mysql_free_result(result);

	printf("\n\n");
    }

    printf(";\n; End of the configuration file for rpm2html\n;\n");
}

void sql_show_metadata(void) {
    MYSQL_RES *result;
    MYSQL_ROW row;


    mysql_query(sql,"SELECT URL FROM Metadata");
    result = mysql_use_result(sql);

    while((row = mysql_fetch_row(result)))
    {
	if (row[0] == NULL)
	    printf("NULL !\n");
	else {
	    printf("%s\n", row[0]);
	}
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
    }

}

void sql_show_mirrors(void) {
    MYSQL_RES *result;
    MYSQL_ROW row;


    mysql_query(sql,"SELECT URL FROM Mirrors");
    result = mysql_use_result(sql);

    while((row = mysql_fetch_row(result)))
    {
	if (row[0] == NULL)
	    printf("NULL !\n");
	else {
	    printf("%s\n", row[0]);
	}
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
    }
}

void sql_show_vendors(void) {
    MYSQL_RES *result;
    MYSQL_ROW row;


    mysql_query(sql,"SELECT Name, URL FROM Vendors");
    result = mysql_use_result(sql);

    while((row = mysql_fetch_row(result)))
    {
	if (row[0] == NULL)
	    printf("NULL !\n");
	else {
	    if (row[1] == NULL)
		printf("%s : no url\n", row[0]);
	    else
		printf("%s : %s\n", row[0], row[1]);
	}
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
    }

}

void sql_show_distribs(void) {
    MYSQL_RES *result;
    MYSQL_ROW row;


    mysql_query(sql,"SELECT Name, Path, URL FROM Distribs");
    result = mysql_use_result(sql);

    while((row = mysql_fetch_row(result)))
    {
	if (row[0] == NULL)
	    printf("NULL !\n");
	else {
	    if (row[1] == NULL)
		printf("%s : no Path\n", row[0]);
	    else {
		if (row[2] == NULL)
		    printf("%s : %s : no url\n", row[0], row[1]);
		else
		    printf("%s : %s : %s\n", row[0], row[1], row[2]);
	    }
	}
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "Error: %s\n", mysql_error(sql));
    }

}

int sql_show_table_stats(const char *table, const char *key) {
    char query[MAX_QUERY];
    MYSQL_RES *result;
    MYSQL_ROW row;
    int res;

    /*
     * Search first for the ID if it already exists
     */
    snprintf(query, MAX_QUERY - 1, "SELECT COUNT(%s) FROM %s", key, table);
    query[MAX_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_show_table_stats: SELECT COUNT failed: %s\n",
	       mysql_error(sql));
	return(-1);
    }

    result = mysql_use_result(sql);
    if (result) {
	while((row = mysql_fetch_row(result)))
	{
	    /*
	     * Lookup the value and return it
	     */
	    if (row[0] == NULL) {
		mysql_free_result(result);
		printf("sql_show_table_stats: select count returns NULL !\n");
		return(-1);
	    }
	    if (sscanf(row[0], "%d", &res) != 1) {
		mysql_free_result(result);
		printf("sql_show_table_stats: value non numeric %s\n", row[0]);
		return(-1);
	    }
	    mysql_free_result(result);
	    if (res <= 0)
		printf("   %s is empty\n", table);
	    else
		printf("   %s contains %d records\n", table, res);
	    return(res);
	}
	mysql_free_result(result);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
    }
    return(-1);
}

int sql_show_stats(void) {
    const char *query = "SHOW TABLES";
    MYSQL_RES *result;
    MYSQL_ROW row;

    int tables = 0;
    int records = 0;

    if (mysql_query(sql,query)) {
	printf("sql_check_tables: SHOW TABLES failed %s\n",
	       mysql_error(sql));
	return(-1);
    }

    result = mysql_use_result(sql);
    if (result) {
	while((row = mysql_fetch_row(result)))
	{
	    if (row[0] == NULL) {
		mysql_free_result(result);
		printf("sql_check_tables: SHOW TABLES returns NULL !\n");
		return(-1);
	    }
	    tables++;
	}
	mysql_free_result(result);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
    }
    printf("%d tables in use\n", tables);
    records += sql_show_table_stats("Config", "Name");
    records += sql_show_table_stats("Distribs", "Name");
    records += sql_show_table_stats("Vendors", "Name");
    records += sql_show_table_stats("Mirrors", "URL");
    records += sql_show_table_stats("Metadata", "URL");
    records += sql_show_table_stats("Packages", "Name");
    records += sql_show_table_stats("Requires", "Resource");
    records += sql_show_table_stats("Provides", "Resource");
    records += sql_show_table_stats("Files", "Path");
    printf("Total: %d records\n", records);
    return(records);
}

/************************************************************************
 *									*
 *			rpm2html configuration functions		*
 *									*
 ************************************************************************/
#ifndef STANDALONE

int readConfigSql(void) {
    char query[MAX_QUERY];
    MYSQL_RES *result;
    MYSQL_ROW row;
    int dir = 0;

    /*
     * General configuration informations
     */
    snprintf(query, MAX_QUERY - 1, "SELECT Name,Value FROM Config");
    query[MAX_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_check_tables: SELECT Config failed %s\n",
	       mysql_error(sql));
	return(-1);
    }

    result = mysql_use_result(sql);
    if (result) {
	while((row = mysql_fetch_row(result)))
	{
	    if ((row[0] == NULL) || (row[1] == NULL)) {
		fprintf(stderr, "readConfigSql : found NULL value\n");
		continue;
	    }
	    if (!strcmp(row[0], "dir"))
		dir = 1;
	    addConfigEntry(RPM2HTML_NAME, row[0], row[1]);
	}
	mysql_free_result(result);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
    }
    if (dir == 0) {
	fprintf(stderr, "readConfigSql : no directory\n");
	return(-1);
    }

    /*
     * The metadata mirror list.
     */
    snprintf(query, MAX_QUERY - 1, "SELECT URL FROM Metadata");
    query[MAX_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_check_tables: SELECT Metadata failed %s\n",
	       mysql_error(sql));
	return(-1);
    }

    result = mysql_use_result(sql);
    if (result) {
	while((row = mysql_fetch_row(result)))
	{
	    if (row[0] == NULL) {
		fprintf(stderr, "readConfigSql : found NULL metadata\n");
		continue;
	    }
	    addConfigEntry("metadata", "mirror", row[0]);
	}
	mysql_free_result(result);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
    }

    /*
     * The distribution lists
     */
    snprintf(query, MAX_QUERY - 1, "SELECT Directory,Name,URL,URLSrc,Path FROM Distribs");
    query[MAX_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_check_tables: SELECT Distribs failed %s\n",
	       mysql_error(sql));
	return(-1);
    }

    result = mysql_use_result(sql);
    if (result) {
	while((row = mysql_fetch_row(result)))
	{
	    if (row[0] == NULL) {
		fprintf(stderr, "readConfigSql : found NULL distro\n");
		continue;
	    }

	    if (row[1] != NULL)
		addConfigEntry(row[0], "name", row[1]);
	    if (row[2] != NULL)
		addConfigEntry(row[0], "ftp", row[2]);
	    if (row[3] != NULL)
		addConfigEntry(row[0], "ftp", row[3]);
	    if (row[4] != NULL)
		addConfigEntry(row[0], "subdir", row[4]);
	}
	mysql_free_result(result);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
    }

    /*
     * The Mirrors
     */
    snprintf(query, MAX_QUERY - 1, "SELECT Distribs.Directory,Mirrors.URL FROM Distribs,Mirrors WHERE Distribs.ID = Mirrors.ID");
    query[MAX_QUERY - 1] = 0;
    if (mysql_query(sql,query)) {
	printf("sql_check_tables: SELECT Distribs failed %s\n",
	       mysql_error(sql));
	return(-1);
    }

    result = mysql_use_result(sql);
    if (result) {
	while((row = mysql_fetch_row(result)))
	{
	    if ((row[0] == NULL) || (row[1] == NULL)) {
		fprintf(stderr, "readConfigSql : found NULL mirror\n");
		continue;
	    }

	    addConfigEntry(row[0], "mirror", row[1]);
	}
	mysql_free_result(result);
    }
    if(mysql_errno(sql)) {
	fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
    }

    /*
     * TODO: add the language(s) stuff
     */
    return(0);
}

void sqlConfigEntry(const char *rpmdir, const char *name, const char *value) {
    int distrib;

    if (rpm2htmlVerbose > 1)
	printf("sqlConfigEntry(\"%s\", \"%s\", \"%s\")\n", rpmdir, name, value);

    /*
     * case of global option for rpm2html.
     */
    if (!strcasecmp(rpmdir, RPM2HTML_NAME)) {
	sql_add_config_info(name, value);
	return;
    }

    /*
     * Options for the metadata mirrors.
     */
    if (!strcasecmp(rpmdir, "metadata")) {
	if (!strcasecmp(name, "mirror")) {
	    sql_add_metadata_base(value);
	} else {
	    printf("Config file : %s entry for [metadata] ignored\n", name);
	}
	return;
    }

    /*
     * option for a directory.
     */
    if (!strcasecmp(name, "name")) {
	sql_add_distrib(value, NULL, rpmdir, NULL, NULL, NULL, NULL,
		        NULL, NULL);
    } else if (!strcasecmp(name, "subdir")) {
	distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
	if (distrib > 0)
            sql_update_id("Distribs", distrib, "Path", value);
    } else if (!strcasecmp(name, "url")) {
	distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
	if (distrib > 0)
            sql_update_id("Distribs", distrib, "URL", value);
    } else if (!strcasecmp(name, "ftp")) {
	distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
	if (distrib > 0)
            sql_update_id("Distribs", distrib, "URL", value);
    } else if (!strcasecmp(name, "ftpsrc")) {
	distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
	if (distrib > 0)
            sql_update_id("Distribs", distrib, "URLSrc", value);
    } else if (!strcasecmp(name, "html")) {
	distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
	if (distrib > 0)
            sql_update_id("Distribs", distrib, "Html", value);
    } else if (!strcasecmp(name, "color")) {
	distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
	if (distrib > 0)
            sql_update_id("Distribs", distrib, "Color", value);
    } else if (!strcasecmp(name, "mirror")) {
	distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
	if (distrib > 0)
	    sql_add_dist_mirror(distrib, value, 0);
    } else {
	printf("Config file : %s entry for [%s] ignored\n", name, rpmdir);
    }
}
#endif

/************************************************************************
 *									*
 *			Main part when compiled standalone		*
 *									*
 ************************************************************************/

#ifdef STANDALONE
void usage(const char *name) {
    printf("%s: usage\n", name);
    printf("	config: dump a config file from the database\n");
    printf("	stats: show database usage statistics\n");
    printf("	stats: show database usage statistics\n");
    printf("	check: remove superfluous entries from the database\n");
    printf("	vendors: list the registered vendors\n");
    printf("	distribs: list the registered distribs\n");
    printf("	metadata: list the registered metadata servers\n");
    printf("	mirrors: list the registered mirrors\n");
    printf("	add distrib name [vendor [directory [path [url [ urlsrc [description]]]]]]\n");
    printf("	add vendor name [url [description]]\n");
    printf("	add mirror distrib url\n");
    exit(1);
}

int main(int argc, char **argv) {
    int res;

    if (argc < 2)
        usage(argv[0]);

    if (init_sql(NULL, NULL, NULL, NULL) < 0)
	exit(1);

    res = sql_check_tables();
    if (res > 0) {
	printf("rebuilt %d tables\n", res);
    }

    if (!strcmp(argv[1], "vendors"))
	sql_show_vendors();
    else if (!strcmp(argv[1], "metadata"))
	sql_show_metadata();
    else if (!strcmp(argv[1], "mirrors"))
	sql_show_mirrors();
    else if (!strcmp(argv[1], "distribs"))
	sql_show_distribs();
    else if (!strcmp(argv[1], "config"))
	sql_show_config();
    else if (!strcmp(argv[1], "stats"))
	sql_show_stats();
    else if (!strcmp(argv[1], "check"))
	sql_check_packages();
    else if (!strcmp(argv[1], "add")) {
	if (argc < 5)
	    usage(argv[0]);
	if (!strcmp(argv[2], "distrib")) {
	    char *Name = NULL;
	    char *Path = NULL;
	    char *Directory = NULL;
	    char *Vendor = NULL;
	    char *URL = NULL;
	    char *URLSrc = NULL;
            char *Description = NULL;
	    char *Color = NULL;
	    char *Html = NULL;
	    if ((argc > 3) && (argv[3][0] != 0))
		Name = argv[3];
	    if ((argc > 4) && (argv[4][0] != 0))
		Vendor = argv[4];
	    if ((argc > 5) && (argv[5][0] != 0))
		Directory = argv[5];
	    if ((argc > 6) && (argv[6][0] != 0))
		Path = argv[6];
	    if ((argc > 7) && (argv[7][0] != 0))
		URL = argv[7];
	    if ((argc > 8) && (argv[8][0] != 0))
		URLSrc = argv[8];
	    if ((argc > 9) && (argv[9][0] != 0))
		Description = argv[9];
	    res = sql_add_distrib(Name, Vendor, Directory, Path,
		                  URL, URLSrc, Description, Color, Html);
	    printf("updated %d fields\n", res);
	} else if (!strcmp(argv[2], "vendor")) {
	    char *Name = NULL;
	    char *URL = NULL;
            char *Description = NULL;
	    if ((argc > 3) && (argv[3][0] != 0))
		Name = argv[3];
	    if ((argc > 4) && (argv[4][0] != 0))
		URL = argv[4];
	    if ((argc > 5) && (argv[5][0] != 0))
		Description = argv[5];
	    res = sql_add_vendor(Name, URL, Description);
	    printf("updated %d fields\n", res);
	} else if (!strcmp(argv[2], "mirror")) {
	    char *Name = NULL;
	    char *URL = NULL;
	    if ((argc > 3) && (argv[3][0] != 0))
		Name = argv[3];
	    if ((argc > 4) && (argv[4][0] != 0))
		URL = argv[4];
	    res = sql_add_mirror(Name, URL, 0);
	    printf("updated %d fields\n", res);
	}
    }

    if (close_sql() < 0)
	return(1);
    exit(0);
}

#endif

Webmaster