distromatic/src/distroquery.c

1670 lines
84 KiB
C

/*
* distroquery - tool for querying data generated by distromatic
*
* Copyright (C) 2013-2020 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 <getopt.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <libintl.h>
#include <locale.h>
#define _(x) gettext(x)
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <dirent.h>
#include <sys/stat.h>
#include <ctype.h>
#include <malloc.h>
#include <string.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 "config.h"
#include "rpmfunctions.h"
#include "functions.h"
// must be as big as ARCHS_MAX (5)
const char* ARCHS[ARCHS_MAX] = { "i586", "x86_64", "arm", "", "" };
static struct configTag *firstconfigtag = NULL;
char *query = "";
char *query_package;
char *query_repository = "devel";
char *query_arch = NULL;
int query_compact = 0;
int query_limit = 10;
int query_offset = 0;
char query_next[PATH_MAX] = "";
char *reply_xmltag = "queryreply";
int reply_plain = 0;
char *lang = "";
int query_archs[ARCHS_MAX] = { 0, 1, 0, 0, 0 };
char *query_path = NULL;
struct configTag *query_repositories[100];
int search_milestone1 = 0, search_milestone2 = 0, search_milestone3 = 0, search_devel = 1;
int search_sources = 0, searchbox = 0;
int search_files = 0;
/* Converts a hex character to its integer value */
char from_hex(char ch) {
return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
}
/* Converts an integer value to its hex character*/
char to_hex(char code) {
static char hex[] = "0123456789abcdef";
return hex[code & 15];
}
/* Returns a url-encoded version of str */
/* IMPORTANT: be sure to free() the returned string after use */
char *url_encode(char *str) {
char *pstr = str, *buf = malloc(strlen(str) * 3 + 1), *pbuf = buf;
while (*pstr) {
if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
*pbuf++ = *pstr;
else if (*pstr == ' ')
*pbuf++ = '+';
else
*pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
pstr++;
}
*pbuf = '\0';
return buf;
}
/* Returns a url-decoded version of str */
/* IMPORTANT: be sure to free() the returned string after use */
char *url_decode(char *str) {
if (!str) { char *buf=malloc(1); buf[0]=0; return buf; }
char *pstr = str, *buf = malloc(strlen(str) + 1), *pbuf = buf;
while (*pstr) {
if (*pstr == '%') {
if (pstr[1] && pstr[2]) {
*pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
pstr += 2;
}
} else if (*pstr == '+') {
*pbuf++ = ' ';
} else {
*pbuf++ = *pstr;
}
pstr++;
}
*pbuf = '\0';
return buf;
}
int sqlite3_find_column_id(sqlite3_stmt *stmt, const char* table, const char* name) {
const char* colname;
int id = 0;
while ((colname = sqlite3_column_name(stmt, id))) {
if (!strcmp(colname, name)) {
if (table) {
if (!strcmp(sqlite3_column_table_name(stmt, id), table)) return id;
} else {
return id;
}
}
id++;
}
return -1;
}
int find_query_arch(char* arch) {
int i;
for (i = 0; i < ARCHS_MAX; i++) {
if (!strcmp(arch, ARCHS[i]) && query_archs[i]) return i;
}
return -1;
}
void printRPMFlags(int flags) {
if (flags & RPMSENSE_LESS) printf("<");
if (flags & RPMSENSE_GREATER) printf(">");
if (flags & RPMSENSE_EQUAL) printf("=");
}
void printTagsLine(const char* arch, const char* tag, const char* group, const char* license) {
if (!arch)
printf("<div class='querytag querytag-red'> %s </div>&nbsp;", _("Source"));
else
printf("<div class='querytag querytag-green'> %s </div>&nbsp;", arch);
printf("<div class='querytag querytag-yellow'> %s </div>&nbsp;"
"<div class='querytag querytag-lightblue'> %s </div>&nbsp;"
"<div class='querytag querytag-orange'> %s </div>",
tag, group, license);
}
char* expandFileFlags(long flags, char *buffer) {
int special = flags >> 9 & 7;
int type = flags >> 12;
sprintf(buffer,"----------");
if (special & 1) buffer[9]='t'; else if (flags & 1<<6) buffer[9]='x';
if (flags & 1<<1) buffer[8]='w';
if (flags & 1<<2) buffer[7]='r';
if (special & 2) buffer[6]='s'; else if (flags & 1<<6) buffer[6]='x';
if (flags & 1<<4) buffer[5]='w';
if (flags & 1<<5) buffer[4]='r';
if (special & 4) buffer[3]='s'; else if (flags & 1<<6) buffer[3]='x';
if (flags & 1<<7) buffer[2]='w';
if (flags & 1<<8) buffer[1]='r';
if (type & 4) buffer[0]='d';
else if (type & 2) buffer[0]='l';
else if (type != 8) buffer[0] = (flags >> 12) + '0';
return buffer;
}
char* resolveFilePath(sqlite3 *db, long id, char *buffer) {
long currid = id;
sqlite3_stmt *stmt;
char sql[PATH_MAX];
buffer[0]='\0';
do {
snprintf(sql, PATH_MAX, "SELECT * FROM files WHERE id=%ld", currid);
if (!sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL) == SQLITE_OK) return NULL;
if (sqlite3_step(stmt) != SQLITE_ROW) return NULL;
snprintf(sql, PATH_MAX, "/%s%s", sqlite3_column_text(stmt,1), buffer);
snprintf(buffer, PATH_MAX, "%s", sql);
currid = sqlite3_column_int(stmt,4); /* parent */
} while (currid >= 0);
return buffer;
}
sqlite3* openRepositoryDatabase(struct configTag* ct, char* arch) {
char dbname[PATH_MAX];
sqlite3* db;
if (arch) {
snprintf(dbname, PATH_MAX, "%s%s-%s.db", ct->repository_dir, ct->tag, arch);
if (sqlite3_open_v2(dbname, (sqlite3**)&db, SQLITE_OPEN_READONLY, NULL)) {
if (db) sqlite3_close(db);
fprintf(stderr, "ERROR: unable to open sqlite3 db %s\n", dbname);
return NULL;
}
} else {
snprintf(dbname, PATH_MAX, "%s%s-sources.db", ct->repository_dir, ct->tag);
if (sqlite3_open_v2(dbname, (sqlite3**)&db, SQLITE_OPEN_READONLY, NULL)) {
if (db) sqlite3_close(db);
fprintf(stderr, "ERROR: unable to open sqlite3 db %s\n", dbname);
return NULL;
}
}
return db;
}
void attachCtDatabases(struct configTag* ct, sqlite3 *db, char* arch) {
char dbname[PATH_MAX];
int i=0;
char sql[PATH_MAX];
char *errmsg;
while (ct->repository[i]) {
if (arch) {
snprintf(dbname, PATH_MAX, "%s%s-%s.db", ct->repository[i]->repository_dir, ct->repository[i]->tag, arch);
snprintf(sql, PATH_MAX, "ATTACH DATABASE '%s' as '%s_%s'", dbname, ct->repository[i]->tag, arch);
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg)) {
fprintf(stderr, "ERROR: unable to exec statement for %s: %s\n", sql, errmsg);
}
} else {
snprintf(dbname, PATH_MAX, "%s%s-sources.db", ct->repository[i]->repository_dir, ct->repository[i]->tag);
snprintf(sql, PATH_MAX, "ATTACH DATABASE '%s' as '%s_sources'", dbname, ct->repository[i]->tag);
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg)) {
fprintf(stderr, "ERROR: unable to exec statement for %s: %s\n", sql, errmsg);
}
}
i++;
}
}
void attachRepositoryDatabases(struct configTag* ct, sqlite3 *db, char* arch, int source) {
char dbname[PATH_MAX];
char sql[PATH_MAX];
char *errmsg;
snprintf(dbname, PATH_MAX, "%s%s-%s.db", ct->repository_dir, ct->tag, arch);
snprintf(sql, PATH_MAX, "ATTACH DATABASE '%s' as '%s_%s'", dbname, ct->tag, arch);
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg)) {
fprintf(stderr, "ERROR: unable to exec statement for %s: %s\n", sql, errmsg);
}
if (source) {
snprintf(dbname, PATH_MAX, "%s%s-sources.db", ct->repository_dir, ct->tag);
snprintf(sql, PATH_MAX, "ATTACH DATABASE '%s' as '%s_sources'", dbname, ct->tag);
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg)) {
fprintf(stderr, "ERROR: unable to exec statement for %s: %s\n", sql, errmsg);
}
}
}
void detachRepositoryDatabases(struct configTag* ct, sqlite3 *db, char* arch, int source) {
char sql[PATH_MAX];
char *errmsg;
snprintf(sql, PATH_MAX, "DETACH DATABASE '%s_%s'", ct->tag, arch);
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg)) {
fprintf(stderr, "ERROR: unable to exec statement for %s: %s\n", sql, errmsg);
}
if (source) {
snprintf(sql, PATH_MAX, "DETACH DATABASE '%s_sources'", ct->tag);
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg)) {
fprintf(stderr, "ERROR: unable to exec statement for %s: %s\n", sql, errmsg);
}
}
}
void printInputForm() {
struct configTag *ct = firstconfigtag;
const char ajax_call[] = "distroquery_request("
// "'repository='+getElementById('repository').value"
"'query='+getElementById('query').value+"
"'&search_devel='+getElementById('search_devel').checked+"
"'&search_milestone3='+getElementById('search_milestone3').checked+"
"'&search_milestone2='+getElementById('search_milestone2').checked+"
"'&search_milestone1='+getElementById('search_milestone1').checked+"
"'&search_i586='+getElementById('search_i586').checked+"
"'&search_x86_64='+getElementById('search_x86_64').checked+"
"'&search_arm='+getElementById('search_arm').checked+"
"'&search_sources='+getElementById('search_sources').checked+"
"'&search_files='+getElementById('search_files').checked"
")";
if (!reply_plain) printf("<queryform><![CDATA[");
printf("<input id=query onkeyup=if(checkMinLength(this.value,3))%s value=\"%s\">", ajax_call, query);
printf("<button onclick=%s>%s</button>", ajax_call, _("Search"));
/* printf("&nbsp;Repository: <select id=repository>");
while (ct) {
printf("<option>%s</option>",ct->tag);
ct = ct->next;
}
printf("</select>");*/
printf("<input type=checkbox id=\"search_devel\" ");
if (search_devel) printf("checked=checked ");
printf("onclick=%s>devel&nbsp;", ajax_call);
printf("<input type=checkbox id=\"search_milestone3\" ");
if (search_milestone3) printf("checked=checked ");
printf("onclick=%s>milestone3&nbsp;", ajax_call);
printf("<input type=checkbox id=\"search_milestone2\" ");
if (search_milestone2) printf("checked=checked ");
printf("onclick=%s>milestone2&nbsp;", ajax_call);
printf("<input type=checkbox id=\"search_milestone1\" ");
if (search_milestone1) printf("checked=checked ");
printf("onclick=%s>milestone1&nbsp;", ajax_call);
printf("&nbsp;<input type=checkbox id=\"search_i586\" ");
if (query_archs[0]) printf("checked=checked ");
printf("onclick=%s>i586&nbsp;", ajax_call);
printf("<input type=checkbox id=\"search_x86_64\" ");
if (query_archs[1]) printf("checked=checked ");
printf("onclick=%s>x86_64&nbsp;", ajax_call);
printf("<input type=checkbox id=\"search_arm\" ");
if (query_archs[2]) printf("checked=checked ");
printf("onclick=%s>arm&nbsp;", ajax_call);
printf("<input type=checkbox id=\"search_sources\" ");
if (search_sources) printf("checked=checked ");
printf("onclick=%s>%s&nbsp;", ajax_call, _("sources"));
printf("<input type=checkbox id=\"search_files\" ");
if (search_files) printf("checked=checked ");
printf("onclick=%s>%s&nbsp;", ajax_call, _("files"));
printf("<br>");
/* ct = firstconfigtag;
while (ct) {
printf("<div width=150px style=\"display:inline\"><input name=\"%s\" type=checkbox value=\"%s\">%s</div>",ct->tag, ct->tag, ct->tag);
ct = ct->next;
}*/
if (!reply_plain) printf("]]></queryform>");
if (!reply_plain) {
printf("<title><![CDATA[");
printf("%s :: %s", _("Search software packages"), ct->configdefaults->distribution_name);
printf("]]></title>");
}
}
int findFileIdFromPath(sqlite3 *db, char** path) {
int frompos = 1, topos;
int parent = -1;
char* pt;
char buffer[PATH_MAX];
char sql[PATH_MAX];
char* linkpath = calloc(strlen(*path),0);
sqlite3_stmt* stmt1;
printf("[<a href='javascript:distroquery_request(\"repository=%s&arch=%s&path=/\")'>ROOT</a>]",
query_repository, query_arch);
while (frompos < strlen(*path)) {
pt = strchr(*path + frompos, '/');
if (pt) topos = pt - *path; else topos = strlen(*path);
strncpy(buffer, *path + frompos, topos - frompos);
buffer[topos-frompos]=0;
snprintf(sql, PATH_MAX, "SELECT id FROM files WHERE parent=%d"
" AND name='%s'", parent, buffer);
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK && sqlite3_step(stmt1) == SQLITE_ROW) {
parent = sqlite3_column_int(stmt1,0);
sqlite3_finalize(stmt1);
strncat(linkpath, "/", strlen(*path) - strlen(linkpath));
strncat(linkpath, buffer, strlen(*path) - strlen(linkpath));
printf("/<a href='javascript:distroquery_request(\"repository=%s&arch=%s&path=%s\")'>%s</a>",
query_repository, query_arch, linkpath, buffer);
}
frompos = topos + 1;
}
/* return clean path */
//free(path);
*path = linkpath;
return parent;
}
void printFileBrowser() {
char dbname[PATH_MAX];
char sql[PATH_MAX];
sqlite3 *dbf;
sqlite3_stmt *stmt1, *stmt2;
int flags, cnt, startid;
struct configTag* ct = findRepositoryByTag(query_repository);
if (!reply_plain) printf("<%s><![CDATA[", reply_xmltag);
if (!query_arch) query_arch=strdup(ARCHS[0]);
snprintf(dbname, PATH_MAX, "%s%s-%s-files.db", ct->repository_dir, ct->tag, query_arch);
if (!sqlite3_open_v2(dbname, &dbf, SQLITE_OPEN_READONLY, NULL)) {
startid = findFileIdFromPath(dbf, &query_path);
snprintf(sql, PATH_MAX, "SELECT * FROM files WHERE"
" parent=%d"
" ORDER BY name", startid);
printf("<table class='queryfiletable'>");
if (sqlite3_prepare_v2(dbf, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt1) == SQLITE_ROW) {
snprintf(sql, PATH_MAX, "SELECT * FROM packages_files_rel,fileusers,filegroups WHERE"
" packages_files_rel.id_file=%d AND"
" packages_files_rel.id_user=fileusers.id AND "
" packages_files_rel.id_group=filegroups.id",
sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "id")));
cnt = 0;
if (sqlite3_prepare_v2(dbf, sql, strlen(sql), &stmt2, NULL) == SQLITE_OK) {
if (sqlite3_step(stmt2) == SQLITE_ROW) {
cnt++;
flags = sqlite3_column_int(stmt2,sqlite3_find_column_id(stmt2, "packages_files_rel", "flags"));
if (flags >> 12 & 4) {
printf("<tr><td>%s</td><td>%s</td><td>%s</td><td width=50%%>"
"<a href='javascript:distroquery_request(\"repository=%s&arch=%s&path=%s/%s\")'>%s</a></td>",
expandFileFlags(flags, sql),
sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, "fileusers", "name")),
sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, "filegroups", "name")),
query_repository,
query_arch,
query_path,
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")),
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")));
} else {
printf("<tr><td>%s</td><td>%s</td><td>%s</td><td width=50%%>%s</td>",
sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, "fileusers", "name")),
sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, "filegroups", "name")),
expandFileFlags(flags, sql),
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")));
}
printf("<td nowrap>%s: %s", _("Provider(s)"), sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, "packages_files_rel", "name")));
while (sqlite3_step(stmt2) == SQLITE_ROW) {
printf(" %s", sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, "packages_files_rel", "name")));
}
printf("</td></tr>");
}
sqlite3_finalize(stmt2);
}
if (cnt == 0) {
printf("<tr><td></td><td></td><td></td><td width=50%%>"
"<a href='javascript:distroquery_request(\"repository=%s&arch=%s&path=%s/%s\")'>%s</a></td>"
"<td></td></tr>",
query_repository,
query_arch,
query_path,
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")),
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")));
}
}
sqlite3_finalize(stmt1);
}
sqlite3_close(dbf);
printf("</table>");
}
if (!reply_plain) printf("]]></%s>", reply_xmltag);
if (!reply_plain) printf("<querystatus><![CDATA[ ]]></querystatus>");
}
int packageVerCmp(int e1, const char* v1, const char* r1, int e2, const char* v2, const char* r2) {
int vcmp = rpmvercmp(v1,v2);
int rcmp = rpmvercmp(r1,r2);
if ((e1 > e2) ||
((e1 == e2) && (vcmp > 0)) ||
((e1 == e2) && (vcmp == 0) && (rcmp >= 0)))
return 1;
else if ((e1 == e2) && (vcmp == 0) && (rcmp == 0))
return 0;
return -1;
}
void printQueryResponse() {
int a, i, j, k, numresults = 0, otherresults = 0, localresults = 0, localprovidesresults = 0, localsourceresults = 0;
char dbname[PATH_MAX];
sqlite3 *dbf;
sqlite3_stmt *statement, *stmt1;
char sql[PATH_MAX];
char buffer[PATH_MAX];
char queryenc[PATH_MAX];
if (!reply_plain) printf("<%s><![CDATA[", reply_xmltag);
strncpy(queryenc, query, PATH_MAX);
for (i = 0; i < strlen(queryenc); i++) {
if (queryenc[i] == ' ') queryenc[i] = '%';
}
for (i = 0; query_repositories[i] != NULL; i++) {
for (a = 0; a < ARCHS_MAX && query_repositories[i]->arch[a]; a++) {
if (find_query_arch(query_repositories[i]->arch[a]) >= 0) {
if (!query_repositories[i]->db[a]) {
snprintf(dbname, PATH_MAX, "%s%s-%s.db",
query_repositories[i]->repository_dir, query_repositories[i]->tag, query_repositories[i]->arch[a]);
if (sqlite3_open_v2(dbname, (sqlite3**)&query_repositories[i]->db[a], SQLITE_OPEN_READONLY, NULL)) {
if (query_repositories[i]->db) sqlite3_close(query_repositories[i]->db[a]);
query_repositories[i]->db[a] = NULL;
fprintf(stderr, "ERROR: unable to open sqlite3 db %s; ignoring.\n", dbname);
}
}
if (!query_repositories[i]->db[ARCHS_MAX]) {
snprintf(dbname, PATH_MAX, "%s%s-sources.db",
query_repositories[i]->repository_dir, query_repositories[i]->tag);
if (sqlite3_open_v2(dbname, (sqlite3**)&query_repositories[i]->db[ARCHS_MAX], SQLITE_OPEN_READONLY, NULL)) {
query_repositories[i]->db[ARCHS_MAX] = NULL;
fprintf(stderr, "ERROR: unable to open sqlite3 db %s; ignoring.\n", dbname);
}
}
if (query_repositories[i]->db[a]) {
localresults = 0;
snprintf(sql, PATH_MAX,
"SELECT * FROM packages WHERE name LIKE '%%%s%%' OR summary LIKE '%%%s%%' OR description LIKE '%%%s%%' OR version LIKE '%%%s%%' "
"ORDER BY name = '%s' DESC, name LIKE '%s%%' DESC, name LIKE '%%%s%%' DESC, "
"groupdescr LIKE 'Graphical Desktop/%%' DESC, groupdescr LIKE 'Applications/%%' DESC, "
"groupdescr LIKE 'Development/%%' ASC, groupdescr LIKE 'Documentation%%' ASC, groupdescr LIKE 'System/Libraries%%' ASC, "
"name LIKE '%%-devel' ASC, name LIKE '%%-debug' ASC "
"LIMIT %d OFFSET %d", queryenc, queryenc, queryenc, queryenc, queryenc, queryenc, queryenc, query_limit, query_offset);
if (sqlite3_prepare_v2((sqlite3*)query_repositories[i]->db[a], sql, strlen(sql), &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
numresults++;
localresults++;
snprintf(sql, PATH_MAX, "SELECT * FROM sources WHERE id=%d",
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id_source")));
if (sqlite3_prepare_v2((sqlite3*)query_repositories[i]->db[ARCHS_MAX], sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
sqlite3_step(stmt1);
get_favicon_from_url((const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "url")),buffer,PATH_MAX);
if (query_compact)
printf("<div class=\"distroquerycompact\" style='position:relative'>");
else
printf("<div style='position:relative'><hr><br>");
printTagsLine(query_repositories[i]->arch[a],
query_repositories[i]->tag,
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "groupdescr")),
(const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "license")));
printf("<br><br><img class=\"distroqueryimg16\" src=\"%s\" width=\"16\" height=\"16\">&nbsp;", buffer);
sqlite3_finalize(stmt1);
}
if (query_compact) {
printf("<b><a href='%s?"
"repository=%s&package=%s&arch=%s&searchbox=true' style=\"color:black\" target='distroquery'>"
"%s</a></b> %s-%s - %s<br>",
query_repositories[i]->configdefaults->url_search_prefix,
query_repositories[i]->tag,
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
query_repositories[i]->arch[a],
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
htmlcleanNoBr((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")),buffer,PATH_MAX));
} else {
printf("<b>%s</b> %s-%s<br>%s",
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
htmlcleanNoBr((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")),buffer,PATH_MAX));
printf("<br><br><div style='text-align:justify;text-justify:inter-word;font-style:italic'>%s</div>",
htmlcleanNoBr((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "description")),buffer,PATH_MAX));
/* install */
/* printf("<div align=right style='position:absolute;top:5px;right:0;padding:5px;'>"
"<div><object type=\"application/x-packagekit-plugin\" width=\"400\" height=\"50\">"
"<param name=\"displayname\" value=\"%s - %s\" />"
"<param name=\"packagenames\" value=\"%s\" /></object></div>",
sqlite3_column_text(statement,1),
sqlite3_column_text(statement,6),
sqlite3_column_text(statement,1));*/
printf("<br>");
/* download */
if (!query_repositories[i]->arch[a]) {
printf("<div class='querytag querytag-green'>"
"&nbsp;<a href=\"%s%s/SRPMS.base/%s-%s-%s.src.rpm\" style=\"color:white\">%s</a>&nbsp;</div>",
query_repositories[i]->download_prefix,
query_repositories[i]->download_dir,
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
_("Download"));
} else {
printf("<div class='querytag querytag-green'>"
"&nbsp;<a href=\"%s%s/RPMS.%s/%s-%s-%s.%s.rpm\" style=\"color:white\">%s</a>&nbsp;</div>",
query_repositories[i]->download_prefix,
query_repositories[i]->download_dir,
query_repositories[i]->arch[a],
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
query_repositories[i]->arch[a],
_("Download"));
}
/* details */
printf("&nbsp;<div class='querytag querytag-lightblue'>"
"&nbsp;<a href=#reply onclick='distroquery_request("
"\"repository=%s&package=%s&arch=%s\")' style=\"color:black\">%s</a>&nbsp;</div>",
query_repositories[i]->tag,
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
query_repositories[i]->arch[a],
_("Details"));
printf("</div><br>");
}
}
}
sqlite3_finalize(statement);
localprovidesresults = 0;
snprintf(sql, PATH_MAX,
"SELECT * FROM packages,provides,provided WHERE "
"(provides.id_package=packages.id AND provided.id=provides.id_provided) "
"AND provided.name LIKE '%%%s%%' "
"ORDER BY provided.name = '%s' DESC, provided.name LIKE '%s%%' DESC, provided.name LIKE '%%%s%%' DESC "
"LIMIT %d OFFSET %d", queryenc, queryenc, queryenc, queryenc, query_limit, query_offset);
if (sqlite3_prepare_v2((sqlite3*)query_repositories[i]->db[a], sql, strlen(sql), &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
numresults++;
if (++localprovidesresults == 1) {
printf("<div style='position:relative'><hr><b>");
if (localresults > 0) printf(_("Other results in "));
else printf(_("Results in"));
printf(" %s %s %s:</b><br>",
query_repositories[i]->tag,
_("for arch "),
query_repositories[i]->arch[a]);
}
if (query_compact) {
printf("<a href='%s?"
"repository=%s&package=%s&arch=%s&searchbox=true' style=\"color:black\" target='distroquery'>"
"%s</a> (%s-%s) %s %s<br>",
query_repositories[i]->configdefaults->url_search_prefix,
query_repositories[i]->tag,
sqlite3_column_text(statement,sqlite3_find_column_id(statement, "packages", "name")),
query_repositories[i]->arch[a],
sqlite3_column_text(statement,sqlite3_find_column_id(statement, "packages", "name")),
sqlite3_column_text(statement,sqlite3_find_column_id(statement, "packages", "version")),
sqlite3_column_text(statement,sqlite3_find_column_id(statement, "packages", "release")),
_("provides"),
sqlite3_column_text(statement,sqlite3_find_column_id(statement, "provided", "name")));
} else {
printf("<a href=#reply onclick='distroquery_request("
"\"repository=%s&package=%s&arch=%s\")' style=\"color:black;background-color:lightblue\">%s</a> (%s-%s) %s %s<br>",
query_repositories[i]->tag,
sqlite3_column_text(statement,sqlite3_find_column_id(statement, "packages", "name")),
query_repositories[i]->arch[a],
sqlite3_column_text(statement,sqlite3_find_column_id(statement, "packages", "name")),
sqlite3_column_text(statement,sqlite3_find_column_id(statement, "packages", "version")),
sqlite3_column_text(statement,sqlite3_find_column_id(statement, "packages", "release")),
_("provides"),
sqlite3_column_text(statement,sqlite3_find_column_id(statement, "provided", "name")));
}
}
}
/* files search */
if (search_files) {
snprintf(dbname, PATH_MAX, "%s%s-%s-files.db",
query_repositories[i]->repository_dir,
query_repositories[i]->tag,
query_repositories[i]->arch[a]);
if (!sqlite3_open_v2(dbname, &dbf, SQLITE_OPEN_READONLY, NULL)) {
snprintf(sql, PATH_MAX, "SELECT * FROM files,packages_files_rel "
"WHERE files.name LIKE '%%%s%%' AND "
"packages_files_rel.id_file = files.id "
"ORDER BY files.name = '%s' DESC, files.name LIKE '%s%%' DESC, "
"files.name LIKE '%%%s%%' DESC LIMIT %d OFFSET %d",
queryenc, queryenc, queryenc, queryenc, query_limit, query_offset);
if (sqlite3_prepare_v2(dbf, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt1) == SQLITE_ROW) {
numresults++;
if (++localprovidesresults == 1) {
printf("<div style='position:relative'><hr><b>");
if (localresults > 0) printf(_("Other results in "));
else printf(_("Results in"));
printf(" %s %s %s:</b><br>",
query_repositories[i]->tag,
_("for arch "),
query_repositories[i]->arch[a]);
}
printf("<a href=#reply onclick='distroquery_request("
"\"repository=%s&package=%s&arch=%s\")' style=\"color:black;background-color:lightblue\">%s</a> (%s-%s)",
query_repositories[i]->tag,
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "packages_files_rel", "name")),
query_repositories[i]->arch[a],
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "packages_files_rel", "name")),
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "packages_files_rel", "version")),
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "packages_files_rel", "release")));
k = sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, "packages_files_rel", "flags"));
if (k >> 12 & 4)
printf(" %s ",_("provides directory"));
else if (k >> 12 & 2)
printf(" %s ",_("provides symbolic link"));
else
printf(" %s ",_("provides file"));
printf("%s<br>",
resolveFilePath(dbf, sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "id_file")), buffer));
}
sqlite3_finalize(stmt1);
}
sqlite3_close(dbf);
}
}
if (localprovidesresults > 0) printf("</div><hr>");
sqlite3_finalize(statement);
}
if ((localresults >= query_limit) || (localprovidesresults >= query_limit)) otherresults = 1;
} /* if query_repository */
} /* archs loop */
} /* repositories loop */
if (search_sources) {
snprintf(sql, PATH_MAX,
"SELECT * FROM sources WHERE name LIKE '%%%s%%' OR summary LIKE '%%%s%%' OR description LIKE '%%%s%%' OR version LIKE '%%%s%%' "
"ORDER BY name = '%s' DESC, name LIKE '%s%%' DESC, name LIKE '%%%s%%' DESC LIMIT %d OFFSET %d",
queryenc, queryenc, queryenc, queryenc, queryenc, queryenc, queryenc, query_limit, query_offset);
for (i = 0; query_repositories[i] != NULL; i++) {
if (!query_repositories[i]->db[ARCHS_MAX]) {
snprintf(dbname, PATH_MAX, "%s%s-sources.db", query_repositories[i]->repository_dir, query_repositories[i]->tag);
if (sqlite3_open_v2(dbname, (sqlite3**)&query_repositories[i]->db[ARCHS_MAX], SQLITE_OPEN_READONLY, NULL)) {
if (query_repositories[i]->db[ARCHS_MAX]) sqlite3_close(query_repositories[i]->db[ARCHS_MAX]);
query_repositories[i]->db[ARCHS_MAX] = NULL;
fprintf(stderr, "ERROR: unable to open sqlite3 db %s; ignoring.\n", dbname);
}
}
if (query_repositories[i]->db[ARCHS_MAX] &&
(sqlite3_prepare_v2((sqlite3*)query_repositories[i]->db[ARCHS_MAX], sql, strlen(sql), &statement, NULL) == SQLITE_OK)) {
localsourceresults = 0;
while (sqlite3_step(statement) == SQLITE_ROW) {
numresults++;
localsourceresults++;
get_favicon_from_url((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "url")),buffer,PATH_MAX);
if (!query_compact) printf("<hr><br>");
printTagsLine(NULL,
query_repositories[i]->tag,
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "groupdescr")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "license")));
printf("<br><img class=\"distroqueryimg16\" src=\"%s\" width=\"16\" height=\"16\">&nbsp;", buffer);
if (query_compact) {
printf("<b><a href='%s?"
"repository=%s&package=%s&searchbox=true' style=\"color:black\" target='distroquery'>"
"%s</a></b> %s-%s - %s<br>",
query_repositories[i]->configdefaults->url_search_prefix,
query_repositories[i]->tag,
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
htmlcleanNoBr((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")),buffer,PATH_MAX));
} else {
printf("<b>%s</b> %s-%s<br>%s<br><br>",
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
htmlcleanNoBr((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")),buffer,PATH_MAX));
printf("<div style='text-align:justify;text-justify:inter-word;font-style:italic'>%s</div>",
htmlcleanNoBr((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "description")),buffer,PATH_MAX));
/* source details */
printf("<div style='display:inline;background-color:lightblue;font-weight:strong'>"
"&nbsp;<a href=#reply onclick='distroquery_request("
"\"repository=%s&package=%s\")' style=\"color:black\">Details</a>&nbsp;</div>",
query_repositories[i]->tag,
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")));
}
}
sqlite3_finalize(statement);
} else {
fprintf(stderr, "ERROR: SQLite: %s (%s)\n", sqlite3_errmsg(query_repositories[i]->db[ARCHS_MAX]), sql);
}
if (localsourceresults >= query_limit) otherresults = 1;
} /* repositories loop */
} /* search_sources */
printf("<hr>");
if (!reply_plain) printf("]]></%s><querystatus><![CDATA[", reply_xmltag);
k = query_offset / query_limit + 1; /* k = current shown page */
if (otherresults || k > 1)
printf("%d %s.", numresults, _("result(s) shown"));
else
printf("%d %s.", numresults, _("result(s) found"));
if (!reply_plain) {
if (k < 7) j=1; else j=k-5; /* j = start pages list from */
if (!otherresults) {
/* current page is last available */
a=k;
j=a-10;
if (j <= 0) j=1;
} else a=j+9; /* a = number of page links displayed */
if (a > 1) {
printf("&nbsp;[&nbsp;");
for (i = j; i <= a; i++) {
if (i != k) printf("<a href=#reply onclick='distroquery_request(\"%s&limit=%d&offset=%d\")'>",
query_next, query_limit, query_limit * (i-1));
printf("%d", i);
printf("</a>&nbsp");
}
printf("]");
}
printf("]]></querystatus>");
printf("<title><![CDATA[");
printf("%s '%s' :: %s", _("Search results for"), query, firstconfigtag->configdefaults->distribution_name);
printf("]]></title>");
}
for (i = 0; query_repositories[i] != NULL; i++) {
for (a = 0; a <= ARCHS_MAX && query_repositories[i]->arch[a]; a++) {
if (query_repositories[i]->db[a]) {
sqlite3_close((sqlite3*)query_repositories[i]->db[a]);
query_repositories[i]->db[a] = NULL;
}
}
}
}
void printSpecialQueryResponse() {
char *repository;
char sql[PATH_MAX];
char buffer[PATH_MAX];
sqlite3 *db;
sqlite3 *dbb = NULL;
sqlite3_stmt *statement, *stmt1;
struct configTag* ct;
int i,a, id, built_for_arch[ARCHS_MAX], built_for_arch_upstream[ARCHS_MAX];
int is_update;
long buildtime;
char updates[PATH_MAX];
char warning[PATH_MAX];
humanDate strdate;
struct tm *ytm;
time_t timesec;
timesec = time(&timesec);
ytm = localtime((time_t *) &timesec);
ytm->tm_sec = 0;
ytm->tm_min = 0;
ytm->tm_hour = 0;
ytm->tm_mday = 1;
ytm->tm_mon = 0;
timesec = mktime(ytm);
if (strstr(query, "$latest$") == query) {
/* latest packages in a repository */
repository = query + 8;
ct = findRepositoryByTag(repository);
if (!ct) return;
db = openRepositoryDatabase(ct, NULL);
attachCtDatabases(ct, db, NULL);
if (ct->arch[0]) {
dbb = openRepositoryDatabase(ct, NULL);
if (!dbb) return;
for (a = 0; a < ARCHS_MAX && ct->arch[a]; a++) {
attachRepositoryDatabases(ct, dbb, ct->arch[a], 0);
}
}
if (!reply_plain) printf("<%s><![CDATA[", reply_xmltag);
snprintf(sql, PATH_MAX, "SELECT * FROM sources ORDER BY buildtime DESC LIMIT 100");
if (db && (sqlite3_prepare_v2(db, sql, strlen(sql), &statement, NULL) == SQLITE_OK)) {
/* loop packages in repository */
while (sqlite3_step(statement) == SQLITE_ROW) {
is_update = 0;
i=0;
updates[0]=0;
warning[0]=0;
/* package in upstream repositories */
for (a = 0; a < ARCHS_MAX; a++) built_for_arch_upstream[a] = 0;
while (ct->repository[i]) {
if (ct->repository[i] == ct) break;
snprintf(sql, PATH_MAX, "SELECT * FROM '%s_sources'.sources WHERE name='%s'",
ct->repository[i]->tag,
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")));
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
if (sqlite3_step(stmt1) == SQLITE_ROW) {
is_update = 1;
snprintf(updates, PATH_MAX, "%s %s(%s,%s-%s)\n", _("Updates"),
(const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")),
ct->repository[i]->tag,
(const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "version")),
(const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "release")));
id = sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "id"));
a = packageVerCmp(
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "epoch")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "epoch")),
(const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "version")),
(const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "release")));
if (a <= 0) {
if (a < 0)
snprintf(warning + strlen(warning), PATH_MAX - strlen(warning),
"%s %s (%d:%s-%s <= %d:%s-%s)\n",
_("Has older version than upstream package in"),
ct->repository[i]->tag,
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "epoch")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "epoch")),
(const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "version")),
(const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "release")));
else
snprintf(warning + strlen(warning), PATH_MAX - strlen(warning), "%s %s",
_("Has same version as upstream package in"),
ct->repository[i]->tag);
}
sqlite3_finalize(stmt1);
/* upstream built for archs */
for (a = 0; a < ARCHS_MAX && ct->repository[i]->arch[a]; a++) {
attachRepositoryDatabases(ct->repository[i], dbb, ct->repository[i]->arch[a], 0);
snprintf(sql, PATH_MAX, "SELECT id FROM '%s_%s'.packages WHERE id_source='%d'",
ct->repository[i]->tag, ct->repository[i]->arch[a], id);
if (sqlite3_prepare_v2(dbb, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt1) == SQLITE_ROW) built_for_arch_upstream[a]++;
sqlite3_finalize(stmt1);
}
detachRepositoryDatabases(ct->repository[i], dbb, ct->repository[i]->arch[a], 0);
}
}
}
i++;
}
/* built for archs */
snprintf(updates + strlen(updates), PATH_MAX - strlen(updates), "\n%s: ", _("Packages for"));
for (a = 0; a < ARCHS_MAX; a++) built_for_arch[a] = 0;
for (a = 0; a < ARCHS_MAX && ct->arch[a]; a++) {
snprintf(sql, PATH_MAX, "SELECT id FROM '%s_%s'.packages WHERE id_source='%d'",
ct->repository[i]->tag, ct->arch[a],
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
if (sqlite3_prepare_v2(dbb, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt1) == SQLITE_ROW) built_for_arch[a]++;
}
sqlite3_finalize(stmt1);
if (built_for_arch[a])
snprintf(updates + strlen(updates), PATH_MAX - strlen(updates), "%s(%d) ", ct->arch[a], built_for_arch[a]);
}
snprintf(updates + strlen(updates), PATH_MAX - strlen(updates), "\n");
for (a = 0; a < ARCHS_MAX; a++) {
if (built_for_arch_upstream[a] && ! built_for_arch[a])
snprintf(warning + strlen(warning), PATH_MAX - strlen(updates), "%s %s\n", _("Needs port to"), ct->arch[a]);
}
/* changelog */
snprintf(sql, PATH_MAX, "SELECT * FROM changelog,packagers "
"WHERE id_source=%d AND changelog.id_packager=packagers.id "
"ORDER BY changelog.time DESC LIMIT 2",
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
snprintf(updates + strlen(updates), PATH_MAX - strlen(updates), "\n%s", _("Latest changes:"));
while (sqlite3_step(stmt1) == SQLITE_ROW) {
snprintf(updates + strlen(updates), PATH_MAX - strlen(updates), "\n%s - %s (%s)\n%s",
(char *)simpleTimeToHuman(sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "time")), (humanDate *) & strdate),
(char *)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "packagers", "name")),
(char *)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "release")),
(char *)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "text")));
}
snprintf(updates + strlen(updates), PATH_MAX - strlen(updates), "\n");
}
get_favicon_from_url((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "url")),buffer,PATH_MAX);
if (is_update) {
printf("<img class=\"distroqueryimg14\" src=\"%s/pkgup.png\" title=\"%s\" width=\"14\" height=\"14\">&nbsp;",
ct->configdefaults->url_dir, updates);
} else {
printf("<img class=\"distroqueryimg14\" src=\"%s/pkg.png\" width=\"14\" height=\"14\">&nbsp;", ct->configdefaults->url_dir);
}
buildtime = sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "buildtime"));
if (buildtime < timesec) {
simpleTimeToTemplate(buildtime,"%Y/%m/%d",&strdate);
} else {
simpleTimeToTemplate(buildtime,"%m/%d",&strdate);
}
printf("%s <img class=\"distroqueryimg12\" src=\"%s\" width=\"12\" height=\"12\">&nbsp;", strdate, buffer);
printf("<b><a href='%s?"
"repository=%s&package=%s&searchbox=true' style=\"color:black\" target='distroquery' title=\"%s\">"
"%s</a></b> %s-%s",
query_repositories[i]->configdefaults->url_search_prefix,
ct->tag,
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
htmlcleanNoBr((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")),buffer,PATH_MAX),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")));
if (warning[0] != 0) {
printf("<img class=\"distroqueryimg14\" src=\"%s/warning-icon.png\" title=\"%s\" width=\"14\" height=\"14\">",
ct->configdefaults->url_dir, warning);
}
printf("<br>");
}
sqlite3_finalize(statement);
}
if (!reply_plain) printf("]]></%s>", reply_xmltag);
if (!reply_plain) {
printf("<title><![CDATA[");
printf("%s :: %s", buffer, firstconfigtag->configdefaults->distribution_name);
printf("]]></title>");
}
} else {
printQueryResponse();
}
}
void printPackageData() {
int i, j;
char dbname[PATH_MAX];
sqlite3 *db, *dbs, *dbf;
sqlite3_stmt *statement, *stmt1, *stmt2;
char sql[PATH_MAX];
char buffer[PATH_MAX];
struct configTag* ct = findRepositoryByTag(query_repository);
humanDate strdate;
sizeString strsize;
FILE *file;
int package_id;
char *package_name = NULL, *package_summary = NULL;
snprintf(dbname, PATH_MAX, "%s%s-%s.db", ct->repository_dir, ct->tag, query_arch);
if (sqlite3_open_v2(dbname, (sqlite3**)&db, SQLITE_OPEN_READONLY, NULL)) {
if (db) sqlite3_close(db);
fprintf(stderr, "ERROR: unable to open sqlite3 db %s\n", dbname);
return;
}
if (!reply_plain) printf("<%s><![CDATA[", reply_xmltag);
snprintf(sql, PATH_MAX, "SELECT * FROM packages WHERE name = '%s'", query_package);
if (db &&
(sqlite3_prepare_v2(db, sql, strlen(sql), &statement, NULL) == SQLITE_OK)) {
if (sqlite3_step(statement) == SQLITE_ROW) {
package_id = sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id"));
package_name = strdup((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")));
package_summary = strdup((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")));
snprintf(dbname, PATH_MAX, "%s%s-sources.db", ct->repository_dir, ct->tag);
if (sqlite3_open_v2(dbname, &dbs, SQLITE_OPEN_READONLY, NULL)) {
if (dbs) sqlite3_close(dbs);
dbs = NULL;
fprintf(stderr, "ERROR: unable to open sqlite3 db %s; aborting.\n", dbname);
return;
}
snprintf(sql, PATH_MAX,
"SELECT * FROM sources,packagers WHERE sources.id=%d AND sources.id_packager=packagers.id",
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id_source")));
if (!sqlite3_prepare_v2(dbs, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
fprintf(stderr, "ERROR: unable to prepare statement for %s; aborting.\n", sql);
return;
}
sqlite3_step(stmt1);
printf("<hr><br>");
printTagsLine(query_arch,
ct->tag,
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "groupdescr")),
(const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "license")));
get_favicon_from_url((const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "url")),buffer,PATH_MAX);
printf("<br><br>"
"<h1><img class=\"distroqueryimg16\" src=\"%s\" width=\"16\" height=\"16\">&nbsp;"
"%s - %s</h1>%s: %s-%s<br>URL: <a href=\"%s\" target=_new>%s</a><br>%s: %s",
buffer,
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")),
_("Version"),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
(const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "url")),
(const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "url")),
_("Size"),
humanSize(sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "size")), &strsize));
printf("<br>%s:", _("Related packages"));
snprintf(sql, PATH_MAX, "SELECT * FROM packages WHERE id_source=%d AND NOT id=%d",
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id_source")),
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt2, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt2) == SQLITE_ROW)
printf(" <a href=#reply onclick='distroquery_request(\"repository=%s&package=%s&arch=%s\")'>%s(%s)</a>",
ct->tag,
(const char*)sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "name")),
query_arch,
(const char*)sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "name")),
query_arch);
sqlite3_finalize(stmt2);
}
printf("<br><br><div style='text-align:justify;text-justify:inter-word;font-style:italic'>%s</div><br>",
htmlclean((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "description")),buffer,PATH_MAX));
/* download */
printf("<div class='querytag querytag-green'>"
"&nbsp;<a href=\"%s%s/RPMS.%s/%s-%s-%s.%s.rpm\" style=\"color:white\">%s</a>&nbsp;</div>",
ct->download_prefix,
ct->download_dir,
query_arch,
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
(const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
query_arch,
_("Download"));
printf("<br><br><hr><br><b>%s:</b>",_("Developers details"));
printf("<br>%s:", _("Source package"));
printf(" <a href=#reply onclick='distroquery_request(\"repository=%s&package=%s\")'>%s</a>",
ct->tag,
(const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")),
(const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")));
snprintf(buffer, PATH_MAX, "%s/specs/%s.spec", ct->repository_dir, query_package);
if ((file = fopen(buffer, "r"))) {
fclose(file);
snprintf(buffer, PATH_MAX, "%s%s/specs/%s.spec", ct->showfile_prefix, ct->download_dir, query_package);
printf("<br>%s: <a href=\"%s\" target=_blank>%s.spec</a>", _("Specfile"), buffer, query_package);
} else {
printf("<br>%s: %s.spec", _("Specfile"), query_package);
}
printf("<br>%s: %s", _("Maintainer"), (const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "packagers", "name")));
printf("<br>%s: %s", _("Build date"),
(char *)simpleTimeToHuman(sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "buildtime")), (humanDate *) & strdate));
/* obsoletes */
snprintf(sql, PATH_MAX, "SELECT * FROM obsoletes WHERE id_package=%d",
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
sqlite3_finalize(stmt1);
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
j=0;
while (sqlite3_step(stmt1) == SQLITE_ROW) {
if (j++ == 0) printf("<br><br>%s:", _("Obsoletes"));
printf(" %s", (const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "obsoletename")));
if (sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "obsoleteversion"))) {
printRPMFlags(sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "obsoleteflags")));
printf("%s", (const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "obsoleteversion")));
}
}
sqlite3_finalize(stmt1);
}
/* provides */
snprintf(sql, PATH_MAX, "SELECT * FROM provides,provided "
"WHERE provides.id_package=%d AND provided.id=provides.id_provided "
"ORDER BY provided.name",
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
j=0;
while (sqlite3_step(stmt1) == SQLITE_ROW) {
if (j++ == 0) printf("<br><br>%s:",_("Provides"));
printf(" %s", (const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")));
if (sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "provideversion"))) {
printRPMFlags(sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "provideflags")));
printf("%s", (const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "provideversion")));
}
}
sqlite3_finalize(stmt1);
}
/* requires */
snprintf(sql, PATH_MAX, "SELECT * FROM requires,provided "
"WHERE requires.id_package=%d AND provided.id=requires.id_provided "
"ORDER BY provided.name",
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
j=0;
while (sqlite3_step(stmt1) == SQLITE_ROW) {
if (j++ == 0) printf("<br><br>%s:", _("Requires"));
printf(" %s", sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")));
if (sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "requireversion"))) {
printRPMFlags(sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "requireflags")));
printf("%s", sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "requireversion")));
}
}
sqlite3_finalize(stmt1);
}
sqlite3_finalize(statement); /* need to finalize all statements before detaching databases */
/* required by */
for (i = 0; query_repositories[i] != NULL; i++) {
attachRepositoryDatabases(query_repositories[i], db, query_arch, 1);
snprintf(sql, PATH_MAX,
"SELECT packagesup.name AS requiredbyname, "
"requiresup.requireflags AS requiredflags, "
"requiresup.requireversion AS requiredversion "
"FROM '%s_%s'.packages AS packagesup,'%s_%s'.requires AS requiresup,"
"'%s_%s'.provided AS providedup,provided,provides "
"WHERE provides.id_package=%d AND provided.id=provides.id_provided "
"AND packagesup.id=requiresup.id_package "
"AND requiresup.id_provided=providedup.id "
"AND providedup.name=provided.name "
"AND NOT packagesup.name='%s' "
"GROUP BY packagesup.name "
"ORDER BY packagesup.name",
query_repositories[i]->tag, query_arch,
query_repositories[i]->tag, query_arch,
query_repositories[i]->tag, query_arch,
package_id, query_package);
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
j=0;
while (sqlite3_step(stmt1) == SQLITE_ROW) {
if (j++ == 0) printf("<br><br>%s %s %s:",_("Required in"),query_repositories[i]->tag,_("by"));
printf(" <a href='javascript:distroquery_request(\"repository=%s&package=%s&arch=%s\")'>%s</a>",
query_repositories[i]->tag,
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "requiredbyname")),
query_arch,
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "requiredbyname")));
if (sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "requiredversion"))) {
printf("(%s %s", _("requires"), query_package);
printRPMFlags(sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "requiredflags")));
printf("%s)", sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "requiredversion")));
}
}
sqlite3_finalize(stmt1);
}
detachRepositoryDatabases(query_repositories[i], db, query_arch, 1);
}
/* build required by */
for (i = 0; query_repositories[i] != NULL; i++) {
attachRepositoryDatabases(query_repositories[i], db, query_arch, 1);
snprintf(sql, PATH_MAX,
"SELECT sourcesup.name as buildrequiredbyname, "
"buildrequiresup.buildrequireflags as buildrequireflags, "
"buildrequiresup.buildrequireversion as buildrequireversion "
"FROM '%s_sources'.sources AS sourcesup,'%s_sources'.buildrequires AS buildrequiresup,"
"provided,provides "
"WHERE provides.id_package=%d AND provided.id=provides.id_provided "
"AND sourcesup.id=buildrequiresup.id_source "
"AND buildrequiresup.buildrequirename=provided.name "
// "AND NOT packagesup.name='%s' "
// "GROUP BY packagesup.name "
"ORDER BY sourcesup.name",
query_repositories[i]->tag, query_repositories[i]->tag, package_id);
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
j=0;
while (sqlite3_step(stmt1) == SQLITE_ROW) {
if (j++ == 0) printf("<br><br>%s %s %s:",_("Build required in"),query_repositories[i]->tag,_("by"));
printf(" <a href='javascript:distroquery_request(\"repository=%s&package=%s\")'>%s</a>",
query_repositories[i]->tag,
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "buildrequiredbyname")),
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "buildrequiredbyname")));
if (sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "buildrequireversion"))) {
printf("(%s %s", _("requires"), query_package);
printRPMFlags(sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "buildrequireflags")));
printf("%s)", sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "buildrequireversion")));
}
}
sqlite3_finalize(stmt1);
}
detachRepositoryDatabases(query_repositories[i], db, query_arch, 1);
}
/* files list */
snprintf(dbname, PATH_MAX, "%s%s-%s-files.db", ct->repository_dir, ct->tag, query_arch);
if (!sqlite3_open_v2(dbname, &dbf, SQLITE_OPEN_READONLY, NULL)) {
printf("<br><br>%s:<br><table class='queryfiletable'>", _("Files list"));
snprintf(sql, PATH_MAX, "SELECT * FROM packages_files_rel,fileusers,filegroups WHERE"
" packages_files_rel.name='%s' AND"
" packages_files_rel.id_user=fileusers.id AND "
" packages_files_rel.id_group=filegroups.id", query_package);
if (sqlite3_prepare_v2(dbf, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt1) == SQLITE_ROW) {
printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>",
expandFileFlags(sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "flags")), sql),
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "fileusers", "name")),
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "filegroups", "name")),
resolveFilePath(dbf, sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "id_file")), buffer));
}
sqlite3_finalize(stmt1);
}
sqlite3_close(dbf);
printf("</table>");
}
sqlite3_close(dbs);
}
snprintf(buffer, PATH_MAX, "%s - %s", package_name, package_summary);
}
if (!reply_plain) printf("]]></%s>", reply_xmltag);
if (!reply_plain) {
printf("<title><![CDATA[");
printf("%s :: %s", buffer, firstconfigtag->configdefaults->distribution_name);
printf("]]></title>");
}
sqlite3_close(db);
db = NULL;
}
void printSourcePackageData() {
int a;
char dbname[PATH_MAX];
sqlite3 *db, *dba;
sqlite3_stmt *statement, *stmt1;
char sql[PATH_MAX];
char buffer[PATH_MAX];
struct configTag* ct = findRepositoryByTag(query_repository);
humanDate strdate;
sizeString strsize;
if (!reply_plain) printf("<%s><![CDATA[", reply_xmltag);
snprintf(dbname, PATH_MAX, "%s%s-sources.db", ct->repository_dir, ct->tag);
if (sqlite3_open_v2(dbname, &db, SQLITE_OPEN_READONLY, NULL)) {
if (db) sqlite3_close(db);
db = NULL;
fprintf(stderr, "ERROR: unable to open sqlite3 db %s; aborting.\n", dbname);
return;
}
snprintf(sql, PATH_MAX,
"SELECT * FROM sources,packagers WHERE sources.name = '%s' AND sources.id_packager=packagers.id", query_package);
if (db &&
(sqlite3_prepare_v2(db, sql, strlen(sql), &statement, NULL) == SQLITE_OK)) {
if (sqlite3_step(statement) == SQLITE_ROW) {
printf("<hr><br>");
printTagsLine(NULL,
ct->tag,
(char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "groupdescr")),
(char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "license")));
get_favicon_from_url((char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "url")),buffer,PATH_MAX);
printf("<br><br>"
"<h1><img class=\"distroqueryimg16\" src=\"%s\" width=\"16\" height=\"16\">&nbsp;"
"%s - %s</h1>%s: %s-%s<br>URL: <a href=\"%s\" target=_new>%s</a><br>Size: %s",
buffer,
(char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
(char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")),
_("Version"),
(char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
(char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
(char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "url")),
(char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "url")),
humanSize(sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "size")), &strsize));
printf("<br>%s:", _("Built packages"));
for (a = 0; a < ARCHS_MAX && ct->arch[a]; a++) {
snprintf(dbname, PATH_MAX, "%s%s-%s.db", ct->repository_dir, ct->tag, ct->arch[a]);
if (!sqlite3_open_v2(dbname, &dba, SQLITE_OPEN_READONLY, NULL)) {
snprintf(sql, PATH_MAX, "SELECT * FROM packages WHERE id_source=%d",
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
if (sqlite3_prepare_v2(dba, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt1) == SQLITE_ROW)
printf(" <a href=#reply onclick='distroquery_request(\"repository=%s&package=%s&arch=%s\")'>%s(%s)</a>",
ct->tag,
(char *)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")),
ct->arch[a],
(char *)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")),
ct->arch[a]);
sqlite3_finalize(stmt1);
}
sqlite3_close(dba);
}
}
printf("<br><br><div style='text-align:justify;text-justify:inter-word;font-style:italic'>%s</div><br>",
htmlclean((char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "description")),buffer,PATH_MAX));
/* download */
printf("<div class='querytag querytag-red'>"
"&nbsp;<a href=\"%s%s/SRPMS.base/%s-%s-%s.src.rpm\" style=\"color:white\">%s</a>&nbsp;</div>",
ct->download_prefix,
ct->download_dir,
(char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
(char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
(char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
_("Download"));
printf("<br><br><hr><br><b>%s:</b>", _("Developers details"));
printf("<br>%s: %s", _("Maintainer"), (char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, "packagers", "name")));
printf("<br>%s: %s", _("Build date"),
(char *)simpleTimeToHuman(sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "buildtime")), (humanDate *) & strdate));
printf("<br><br>%s:", _("Source files"));
snprintf(sql, PATH_MAX,
"SELECT * FROM sources_source WHERE id_source=%d",
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt1) == SQLITE_ROW) {
printf(" %s", (char *)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "source")));
}
sqlite3_finalize(stmt1);
}
printf("<br><br>%s:", _("Patches"));
snprintf(sql, PATH_MAX,
"SELECT * FROM sources_patch WHERE id_source=%d",
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt1) == SQLITE_ROW) {
printf(" %s", (char *)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "patch")));
}
sqlite3_finalize(stmt1);
}
printf("<br><br>%s:", _("Build requirements"));
snprintf(sql, PATH_MAX, "SELECT * FROM buildrequires WHERE id_source=%d",
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt1) == SQLITE_ROW) {
printf(" %s", (char *)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "buildrequirename")));
if (strcmp("", (char *)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "buildrequireversion")))) {
printRPMFlags(sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "buildrequireflags")));
printf("%s", (char *)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "buildrequireversion")));
}
}
sqlite3_finalize(stmt1);
}
printf("<br><br>%s:<br>", _("Changelog"));
snprintf(sql, PATH_MAX,
"SELECT * FROM changelog,packagers WHERE id_source=%d AND changelog.id_packager=packagers.id",
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt1) == SQLITE_ROW) {
printf("%s - %s (%s)<br><pre>%s</pre>",
(char *)simpleTimeToHuman(sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "time")), (humanDate *) & strdate),
(char *)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "packagers", "name")),
(char *)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "release")),
(char *)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "text")));
}
sqlite3_finalize(stmt1);
}
}
snprintf(buffer, PATH_MAX, "%s - %s",
(char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
(char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")));
sqlite3_finalize(statement);
}
if (!reply_plain) printf("]]></%s>", reply_xmltag);
if (!reply_plain) {
printf("<title><![CDATA[");
printf("%s :: %s", buffer, firstconfigtag->configdefaults->distribution_name);
printf("]]></title>");
}
sqlite3_close(db);
db = NULL;
}
void parse_request_variables(char *data) {
char *vartok, *valuetok;
struct configTag *ct = firstconfigtag;
int i;
while (1) {
vartok = (char *) strtok(data, "=");
if (data) data = NULL;
if (!vartok || (vartok[0] == '\0') ) break;
valuetok = (char *) strtok(NULL, "&");
if (!strcmp(vartok, "repository")) {
query_repository = valuetok;
} else if (!strcmp(vartok, "package")) {
query_package = valuetok;
} else if (!strcmp(vartok, "arch")) {
query_arch = valuetok;
} else if (!strcmp(vartok, "offset")) {
query_offset = atoi(url_decode(valuetok));
if (query_offset < 0) query_offset = 0;
} else if (!strcmp(vartok, "limit")) {
query_limit = atoi(url_decode(valuetok));
if (query_limit < 0) query_limit = 10;
else if (query_limit > 20) query_limit = 20;
} else if (!strcmp(vartok, "searchbox")) {
searchbox = strstr(valuetok, "false") != valuetok;
} else if (!strcmp(vartok, "lang")) {
lang = valuetok;
} else if (!strcmp(vartok, "replytag")) {
reply_xmltag = valuetok;
} else if (!strcmp(vartok, "replyplain")) {
reply_plain = strstr(valuetok, "true") == valuetok;
} else if (!strcmp(vartok, "query_compact")) {
query_compact = strstr(valuetok, "true") == valuetok;
} else if (!strcmp(vartok, "path")) {
query_path = valuetok;
} else {
/* fields to make reusable query string for next pages */
if (!strcmp(vartok, "query")) {
query = url_decode(valuetok);
} else if (!strcmp(vartok, "search_milestone3")) {
search_milestone3 = strstr(valuetok, "false") != valuetok;
} else if (!strcmp(vartok, "search_milestone2")) {
search_milestone2 = strstr(valuetok, "false") != valuetok;
} else if (!strcmp(vartok, "search_milestone1")) {
search_milestone1 = strstr(valuetok, "false") != valuetok;
} else if (!strcmp(vartok, "search_devel")) {
search_devel = strstr(valuetok, "false") != valuetok;
} else if (!strcmp(vartok, "search_i586")) {
query_archs[0] = strstr(valuetok, "false") != valuetok;
} else if (!strcmp(vartok, "search_x86_64")) {
query_archs[1] = strstr(valuetok, "false") != valuetok;
} else if (!strcmp(vartok, "search_arm")) {
query_archs[2] = strstr(valuetok, "false") != valuetok;
} else if (!strcmp(vartok, "search_sources")) {
search_sources = strstr(valuetok, "false") != valuetok;
} else if (!strcmp(vartok, "search_files")) {
search_files = strstr(valuetok, "false") != valuetok;
}
if (vartok && valuetok) {
strncat(query_next, vartok, sizeof(query_next) - strlen(query_next));
strncat(query_next, "=", sizeof(query_next) - strlen(query_next));
strncat(query_next, valuetok, sizeof(query_next) - strlen(query_next));
strncat(query_next, "&", sizeof(query_next) - strlen(query_next));
}
}
}
if (query_next[strlen(query_next)] == '&') query_next[strlen(query_next)] = '\0';
ct = firstconfigtag;
i = 0;
if (query_package) {
if (strstr(query_repository, "devel") == query_repository) {
search_devel = 1;
search_milestone3 = 0;
search_milestone2 = 0;
search_milestone1 = 0;
} else if (strstr(query_repository, "milestone3") == query_repository) {
search_devel = 0;
search_milestone3 = 1;
search_milestone2 = 0;
search_milestone1 = 0;
} else if (strstr(query_repository, "milestone2") == query_repository) {
search_devel = 0;
search_milestone3 = 0;
search_milestone2 = 1;
search_milestone1 = 0;
} else if (strstr(query_repository, "milestone1") == query_repository) {
search_devel = 0;
search_milestone3 = 0;
search_milestone2 = 0;
search_milestone1 = 1;
}
}
while (ct) {
if ((strstr(ct->tag, "devel") == ct->tag) && search_devel) query_repositories[i++] = ct;
ct = ct->next;
}
ct = firstconfigtag;
while (ct) {
if ((strstr(ct->tag, "milestone3") == ct->tag) && search_milestone3) query_repositories[i++] = ct;
ct = ct->next;
}
ct = firstconfigtag;
while (ct) {
if ((strstr(ct->tag, "milestone2") == ct->tag) && search_milestone2) query_repositories[i++] = ct;
ct = ct->next;
}
ct = firstconfigtag;
while (ct) {
if ((strstr(ct->tag, "milestone1") == ct->tag) && search_milestone1) query_repositories[i++] = ct;
ct = ct->next;
}
query_repositories[i++] = NULL;
}
int
main(int argc, char *argv[])
{
char *data;
int responsed = 0;
// install backtrace handler
signal(SIGSEGV, backtraceHandler);
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)) {
parse_request_variables(data);
}
if (!reply_plain)
printf("Content-Type: text/xml;charset=utf-8\n\n<distroquery>");
else
printf("Content-Type: text/html;charset=utf-8\n\n");
setlocale(LC_ALL, lang);
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
if (query_package && strlen(query_package)) {
if (query_arch)
printPackageData();
else
printSourcePackageData();
responsed = 1;
} else if (query && strlen(query)) {
if (query[0] == '$')
printSpecialQueryResponse();
else
printQueryResponse();
responsed = 1;
} else if (query_path) {
printFileBrowser();
}
if (!responsed || (responsed && searchbox)) printInputForm();
if (!reply_plain) printf("</distroquery>\n");
exit(0);
}