/* * 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 #include #include #define _(x) gettext(x) #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" // 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 = "milestone2"; 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] = { 1, 0, 0, 0, 0 }; char *query_path = NULL; struct configTag *query_repositories[100]; int search_milestone1 = 0, search_milestone2 = 1, 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("
%s
 ", _("Source")); else printf("
%s
 ", arch); printf("
%s
 " "
 %s 
 " "
 %s 
", 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_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("", ajax_call, query); printf("", ajax_call, _("Search")); /* printf(" Repository: ");*/ printf("devel ", ajax_call); printf("milestone2 ", ajax_call); printf("milestone1 ", ajax_call); printf(" i586 ", ajax_call); printf("x86_64 ", ajax_call); printf("arm ", ajax_call); printf("%s ", ajax_call, _("sources")); printf("%s ", ajax_call, _("files")); printf("
"); /* ct = firstconfigtag; while (ct) { printf("
%s
",ct->tag, ct->tag, ct->tag); ct = ct->next; }*/ if (!reply_plain) printf("]]>
"); if (!reply_plain) { printf("<![CDATA["); printf("%s :: %s", _("Search software packages"), ct->configdefaults->distribution_name); printf("]]>"); } } 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("[ROOT]", 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); strcat(linkpath, "/"); strncat(linkpath, buffer, strlen(*path) - strlen(linkpath)); printf("/%s", 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>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(""); 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("" "" "", 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), 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("" "", 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(""); } sqlite3_finalize(stmt2); } if (cnt == 0) { printf("" "" "", 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("
%s%s%s" "%s
%s%s%s%s%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("
%s
"); } if (!reply_plain) printf("]]>", reply_xmltag); if (!reply_plain) printf(""); } 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>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("
"); else printf("


"); 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("
 ", buffer); sqlite3_finalize(stmt1); } if (query_compact) { printf("" "%s %s-%s - %s
", 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("%s %s-%s
%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("

%s
", htmlcleanNoBr((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "description")),buffer,PATH_MAX)); /* install */ /* printf("
" "
" "" "
", sqlite3_column_text(statement,1), sqlite3_column_text(statement,6), sqlite3_column_text(statement,1));*/ /* download */ printf("
" " %s 
", 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")); /* details */ printf(" 
" " %s 
", query_repositories[i]->tag, sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")), query_repositories[i]->arch[a], _("Details")); printf("

"); } } } 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("

"); if (localresults > 0) printf(_("Other results in ")); else printf(_("Results in")); printf(" %s %s %s:
", query_repositories[i]->tag, _("for arch "), query_repositories[i]->arch[a]); } if (query_compact) { printf("" "%s (%s-%s) %s %s
", 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("%s (%s-%s) %s %s
", 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("

"); if (localresults > 0) printf(_("Other results in ")); else printf(_("Results in")); printf(" %s %s %s:
", query_repositories[i]->tag, _("for arch "), query_repositories[i]->arch[a]); } printf("%s (%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
", 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("

"); 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("

"); 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("
 ", buffer); if (query_compact) { printf("" "%s %s-%s - %s
", 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("%s %s-%s
%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("
%s
", htmlcleanNoBr((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "description")),buffer,PATH_MAX)); /* source details */ printf("
" " Details 
", 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("
"); if (!reply_plain) printf("]]> 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(" [ "); for (i = j; i <= a; i++) { if (i != k) printf("", query_next, query_limit, query_limit * (i-1)); printf("%d", i); printf(" "); } printf("]"); } printf("]]>"); printf("<![CDATA["); printf("%s '%s' :: %s", _("Search results for"), query, firstconfigtag->configdefaults->distribution_name); printf("]]>"); } 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(×ec); ytm = localtime((time_t *) ×ec); 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>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(" ", ct->configdefaults->url_dir, updates); } else { printf(" ", 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  ", strdate, buffer); printf("" "%s %s-%s", 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("", ct->configdefaults->url_dir, warning); } printf("
"); } sqlite3_finalize(statement); } if (!reply_plain) printf("]]>", reply_xmltag); if (!reply_plain) { printf("<![CDATA["); printf("%s :: %s", buffer, firstconfigtag->configdefaults->distribution_name); printf("]]>"); } } 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>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("

"); 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("

" "

 " "%s - %s

%s: %s-%s
URL: %s
%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("
%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(" %s(%s)", 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("

%s

", htmlclean((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "description")),buffer,PATH_MAX)); /* download */ printf("
" " %s 
", 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("

%s:",_("Developers details")); printf("
%s:", _("Source package")); printf(" %s", 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("
%s: %s.spec", _("Specfile"), buffer, query_package); } else { printf("
%s: %s.spec", _("Specfile"), query_package); } printf("
%s: %s", _("Maintainer"), (const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "packagers", "name"))); printf("
%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("

%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("

%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("

%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("

%s %s %s:",_("Required in"),query_repositories[i]->tag,_("by")); printf(" %s", 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("

%s %s %s:",_("Build required in"),query_repositories[i]->tag,_("by")); printf(" %s", 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("

%s:
", _("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("", sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "fileusers", "name")), sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "filegroups", "name")), expandFileFlags(sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "flags")), sql), resolveFilePath(dbf, sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "id_file")), buffer)); } sqlite3_finalize(stmt1); } sqlite3_close(dbf); printf("
%s%s%s%s
"); } sqlite3_close(dbs); } snprintf(buffer, PATH_MAX, "%s - %s", package_name, package_summary); } if (!reply_plain) printf("]]>", reply_xmltag); if (!reply_plain) { printf("<![CDATA["); printf("%s :: %s", buffer, firstconfigtag->configdefaults->distribution_name); printf("]]>"); } 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>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("

"); 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("

" "

 " "%s - %s

%s: %s-%s
URL: %s
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("
%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(" %s(%s)", 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("

%s

", htmlclean((char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "description")),buffer,PATH_MAX)); /* download */ printf("
" " %s 
", 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("

%s:", _("Developers details")); printf("
%s: %s", _("Maintainer"), (char *)sqlite3_column_text(statement,sqlite3_find_column_id(statement, "packagers", "name"))); printf("
%s: %s", _("Build date"), (char *)simpleTimeToHuman(sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "buildtime")), (humanDate *) & strdate)); printf("

%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("

%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("

%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("

%s:
", _("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)
%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"))); } 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("]]>", reply_xmltag); if (!reply_plain) { printf("<![CDATA["); printf("%s :: %s", buffer, firstconfigtag->configdefaults->distribution_name); printf("]]>"); } 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_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) { strcat(query_next, vartok); strcat(query_next, "="); strcat(query_next, valuetok); strcat(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_milestone2 = 0; search_milestone1 = 0; searchbox = 1; } else if (strstr(query_repository, "milestone2") == query_repository) { search_devel = 0; search_milestone2 = 1; search_milestone1 = 0; searchbox = 1; } else if (strstr(query_repository, "milestone1") == query_repository) { search_devel = 0; search_milestone2 = 0; search_milestone1 = 1; searchbox = 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, "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"); 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("\n"); exit(0); }