distromatic/src/distroquery.c

215 lines
6.6 KiB
C
Raw Normal View History

/*
* distroquery - tool for querying data generated by distromatic
*
* Copyright (C) 2013 by Silvan Calarco <silvan.calarco@mambasoft.it>
*
* 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 <getopt.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <dirent.h>
#include <sys/stat.h>
#if HAVE_STRING_H
# if !STDC_HEADERS && HAVE_MEMORY_H
# include <memory.h>
# endif
/* Tell glibc's <string.h> to provide a prototype for strndup() */
# ifndef __USE_GNU
# define __USE_GNU
# endif
# include <string.h>
#endif
#if HAVE_STRINGS_H
# include <strings.h>
#endif
/* Tell glibc's <time.h> to provide a prototype for strptime() */
#ifndef __USE_XOPEN
# define __USE_XOPEN
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#if !HAVE_STRCHR
# define strchr index
#endif
#include <sqlite3.h>
#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("<queryform><![CDATA[");
printf("<input id=query onkeypress=if(checkEnter(event))ajax_getvalues('repository='+getElementById('repository').value+'&query='+getElementById('query').value);>");
printf("<button onclick=ajax_getvalues('repository='+getElementById('repository').value+'&query='+getElementById('query').value);>Cerca</button>");
printf("&nbsp;Repository: <select id=repository>");
while (ct) {
printf("<option>%s</option>",ct->tag);
ct = ct->next;
}
printf("</select>");
printf("]]></queryform>");
}
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, "%sdistromatic.db", configtag->repository[i]->repository_dir);
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("<queryreply><![CDATA[");
printf("<h2>Binaries:</h2>");
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("<b>%s</b> %s:%s-%s<br>%s<br>Group: %s<br><br><i>%s</i><br><hr>",
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("<h2>Sources:</h2>");
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("<b>%s</b> %s:%s-%s<br>%s<br>Group: %s<br>License: %s</br>URL: %s<br><br><i>%s</i><br><hr>",
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("]]></queryreply>");
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<distroquery>");
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 (data && strlen(data)) {
print_xml_reply(data);
printf("</distroquery>\n");
exit(0);
}
printInputForm(data);
printf("</distroquery>\n");
exit(0);
}