From 39987f518a76a2b117241ab5d361bf7539a218db Mon Sep 17 00:00:00 2001 From: Silvan Calarco Date: Mon, 7 Oct 2013 02:36:11 +0200 Subject: [PATCH] distroquery: early-stage cgi interfacing to sqlite3 dbs --- src/Makefile.am | 13 ++- src/distroquery.c | 214 ++++++++++++++++++++++++++++++++++++++ src/include/distromatic.h | 1 + 3 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 src/distroquery.c diff --git a/src/Makefile.am b/src/Makefile.am index 8c4cba6..852f0de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/include -I$(top_builddir)/src/include -rdynami LDFLAGS += $(SQLITE_LIBS) -lpthread -rdynamic -bin_PROGRAMS = distromatic +bin_PROGRAMS = distromatic distroquery distromatic_SOURCES = \ buildtools.c \ @@ -32,4 +32,15 @@ distromatic_SOURCES = \ rpmfunctions.c \ backend-sqlite3.c +distroquery_SOURCES = \ + buildtools.c \ + changelog.c \ + distroquery.c \ + functions.c \ + reports.c \ + headerlist.c \ + requirelist.c \ + rpmfunctions.c \ + backend-sqlite3.c + SUBDIRS = include missing diff --git a/src/distroquery.c b/src/distroquery.c new file mode 100644 index 0000000..cd0fee2 --- /dev/null +++ b/src/distroquery.c @@ -0,0 +1,214 @@ +/* + * distroquery - tool for querying data generated by distromatic + * + * Copyright (C) 2013 by Silvan Calarco + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of version 2 of the GNU General Public License as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, to the extent permitted by law; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#if HAVE_UNISTD_H +# include +#endif + +#include +#include + +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +/* Tell glibc's to provide a prototype for strndup() */ +# ifndef __USE_GNU +# define __USE_GNU +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif + +/* Tell glibc's to provide a prototype for strptime() */ +#ifndef __USE_XOPEN +# define __USE_XOPEN +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#if !HAVE_STRCHR +# define strchr index +#endif + +#include +#include "distromatic.h" +#include "functions.h" + +static struct configTag *firstconfigtag = NULL, *configtag = NULL; +char *repository_tag = NULL; +char *query; + +void printInputForm(char *data) { + struct configTag *ct = firstconfigtag; + + printf(""); + printf(""); + printf(" Repository: "); + printf("]]>"); +} + + +void printQueryData(char* repository_tag, char* query) { + + int i; + + configtag = findRepositoryByTag(repository_tag); + if (!configtag) { + fprintf(stderr, "Fatal error: configuration missing for given tag\n"); + exit(1); + } + + char dbname[PATH_MAX]; + + for (i = 0; i <= configtag->repository_level; i++) { + snprintf(dbname, PATH_MAX, "%s%s.db", configtag->configdefaults->html_basedir, configtag->repository[i]->tag); + if (sqlite3_open_v2(dbname, (sqlite3**)&configtag->repository[i]->db, SQLITE_OPEN_READONLY, NULL)) { + if (configtag->repository[i]->db) sqlite3_close(configtag->repository[i]->db); + fprintf(stderr, "ERROR: unable to open sqlite3 db %s; aborting.\n", dbname); + return; + } + } + + sqlite3_stmt *statement; + char sql[PATH_MAX]; + int j; + + printf("Binaries:"); + int a; + for (a = 0; a < ARCHS_MAX && configtag->arch[a]; a++) { + snprintf(sql, PATH_MAX, "SELECT * FROM packages_%s WHERE name LIKE '%%%s%%' OR summary LIKE '%%%s%%' OR description LIKE '%%%s%%'", configtag->arch[a], query, query, query); + for (i = 0; i <= configtag->repository_level; i++) { + if (sqlite3_prepare_v2((sqlite3*)configtag->repository[i]->db, sql, strlen(sql), &statement, NULL) == SQLITE_OK) { + while (sqlite3_step(statement) == SQLITE_ROW) { + printf("%s %s:%s-%s
%s
Group: %s

%s

", + sqlite3_column_text(statement,1), + sqlite3_column_text(statement,3), + sqlite3_column_text(statement,4), + sqlite3_column_text(statement,5), + sqlite3_column_text(statement,6), + sqlite3_column_text(statement,7), + sqlite3_column_text(statement,8)); + } + } + printf("\n"); + } + } + + printf("

Sources:

"); + snprintf(sql, PATH_MAX, "SELECT * FROM sources WHERE name LIKE '%%%s%%' OR summary LIKE '%%%s%%' OR description LIKE '%%%s%%'", query, query, query); + for (i = 0; i <= configtag->repository_level; i++) { + if (sqlite3_prepare_v2((sqlite3*)configtag->repository[i]->db, sql, strlen(sql), &statement, NULL) == SQLITE_OK) { + while (sqlite3_step(statement) == SQLITE_ROW) { + printf("%s %s:%s-%s
%s
Group: %s
License: %s
URL: %s

%s

", + sqlite3_column_text(statement,1), + sqlite3_column_text(statement,3), + sqlite3_column_text(statement,4), + sqlite3_column_text(statement,5), + sqlite3_column_text(statement,6), + sqlite3_column_text(statement,8), + sqlite3_column_text(statement,11), + sqlite3_column_text(statement,10), + sqlite3_column_text(statement,9)); + } + } + printf("\n"); + } + + printf("]]>
"); + for (i = 0; i <= configtag->repository_level; i++) { + sqlite3_close((sqlite3*)configtag->repository[i]->db); + } + + +} + + +void print_xml_reply(char *data) { + char *vartok, *valuetok; + + while (1) { + vartok = (char *) strtok(data, "="); + if (data) data = NULL; + if (!vartok || (vartok[0] == '\0') ) break; + valuetok = (char *) strtok(NULL, "&"); + if (strstr(vartok, "repository")) { + repository_tag = valuetok; + } else if (strstr(vartok, "query")) { + query = valuetok; + } + } + printQueryData(repository_tag, query); +} + + +int +main(int argc, char *argv[]) +{ + char *repository_dir = NULL; +// char *configfile = NULL; + char *data; + + printf("Content-Type: text/xml;charset=utf-8\n\n"); + + firstconfigtag = read_configuration(DEFAULT_CONFIGFILE); + if (!firstconfigtag) { + fprintf(stderr, "Fatal error while parsing config file " DEFAULT_CONFIGFILE "; aborting.\n"); + exit(1); + } + + data = getenv("QUERY_STRING"); + if (strlen(data)) { + print_xml_reply(data); + printf("\n"); + exit(0); + } + + printInputForm(data); + + printf("\n"); + exit(0); +} diff --git a/src/include/distromatic.h b/src/include/distromatic.h index 5de62e1..57cc1c5 100644 --- a/src/include/distromatic.h +++ b/src/include/distromatic.h @@ -39,6 +39,7 @@ struct configTag { struct fileTree *filetree[ARCHS_MAX]; struct headerStats stats; struct configTag *next; + void *db; }; #endif