diff --git a/src/backend-sqlite3.c b/src/backend-sqlite3.c
index c89b32b..51a22aa 100644
--- a/src/backend-sqlite3.c
+++ b/src/backend-sqlite3.c
@@ -101,12 +101,18 @@ int SQLite_print_contents_subtree(sqlite3 *db,
"name STRING, firstchild INTEGER, next INTEGER, parent INTEGER, numproviders INTEGER"
/* struct headerList **provider; */
-#define SQLITE_TABLE_packages_files_rel "id INTEGER PRIMARY KEY, id_package INTEGER, id_file INTEGER, name STRING, version STRING, release STRING"
+#define SQLITE_TABLE_packages_files_rel "id INTEGER PRIMARY KEY, id_package INTEGER, id_file INTEGER, "\
+ "id_user INTEGER, id_group INTEGER, flags INTEGER, "\
+ "name STRING, version STRING, release STRING"
+#define SQLITE_TABLE_fileusers "id INTEGER PRIMARY KEY, name STRING"
+#define SQLITE_TABLE_filegroups "id INTEGER PRIMARY KEY, name STRING"
int generateSQLite_files(struct configTag* ct, sqlite3 *db, int arch) {
int i;
struct headerList* currpackage;
+ struct fileUserList *fileUser = ct->fileuserlist[arch];
+ struct fileGroupList *fileGroup = ct->filegrouplist[arch];
snprintf(sqlite3_query, PATH_MAX, "packages_files_rel");
SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_packages_files_rel);
@@ -114,22 +120,60 @@ int generateSQLite_files(struct configTag* ct, sqlite3 *db, int arch) {
snprintf(sqlite3_query, PATH_MAX, "files");
SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_files);
+ snprintf(sqlite3_query, PATH_MAX, "fileusers");
+ SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_fileusers);
+
+ snprintf(sqlite3_query, PATH_MAX, "filegroups");
+ SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_filegroups);
+
+ while (fileUser) {
+ snprintf(sqlite3_query, PATH_MAX, "INSERT INTO fileusers VALUES(%d,?);",
+ fileUser->id);
+ if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
+ fprintf(stderr, "ERROR: sqlite3_prepare_v2: %s (%s)\n", sqlite3_errmsg(db), sqlite3_query);
+ return 1;
+ }
+ sqlite3_bind_text(stmt, 1, fileUser->name, -1, SQLITE_STATIC);
+ if (sqlite3_step(stmt) != SQLITE_DONE) {
+ fprintf(stderr, "ERROR: sqlite3_step: %s (%s)\n", sqlite3_query, sqlite3_errmsg(db));
+ return 3;
+ }
+ sqlite3_finalize(stmt);
+ fileUser = fileUser->next;
+ }
+
+ while (fileGroup) {
+ snprintf(sqlite3_query, PATH_MAX, "INSERT INTO filegroups VALUES(%d,?);",
+ fileGroup->id);
+ if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
+ fprintf(stderr, "ERROR: sqlite3_prepare_v2: %s (%s)\n", sqlite3_errmsg(db), sqlite3_query);
+ return 1;
+ }
+ sqlite3_bind_text(stmt, 1, fileGroup->name, -1, SQLITE_STATIC);
+ if (sqlite3_step(stmt) != SQLITE_DONE) {
+ fprintf(stderr, "ERROR: sqlite3_step: %s (%s)\n", sqlite3_query, sqlite3_errmsg(db));
+ return 3;
+ }
+ sqlite3_finalize(stmt);
+ fileGroup = fileGroup->next;
+ }
+
SQLite_begin_transaction(db);
if (SQLite_print_contents_subtree(db, ct->filetree[arch], ct, arch)) return 1;
-/* if (sqlite3_finalize(stmt)) {
- fprintf(stderr, "ERROR: SQLite: (%s) %s", sqlite3_query, sqlite3_errmsg(db));
- }*/
-
currpackage = ct->headerlist[arch];
while (currpackage) {
/* packages <-> files relations */
for (i = 0; i < currpackage->filenamecount; i++) {
- snprintf(sqlite3_query, PATH_MAX, "INSERT INTO packages_files_rel VALUES(NULL,%d,%d,?,?,?);",
+ snprintf(sqlite3_query, PATH_MAX, "INSERT INTO packages_files_rel VALUES(NULL,%d,%d,%d,%d,%d,?,?,?);",
currpackage->id,
- currpackage->file[i]->id);
+ currpackage->file[i]->id,
+ currpackage->fileuser[i]->id,
+ currpackage->filegroup[i]->id,
+ currpackage->fileflags[i]);
if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
fprintf(stderr, "ERROR: sqlite3_prepare_v2: %s (%s)\n", sqlite3_errmsg(db), sqlite3_query);
+ return 1;
}
sqlite3_bind_text(stmt, 1, currpackage->name, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, currpackage->version, -1, SQLITE_STATIC);
@@ -174,6 +218,7 @@ int generateSQLite_provided(struct configTag* ct, sqlite3 *db, int arch) {
sqlite3_bind_text(stmt, 1, provided->name, -1, SQLITE_STATIC);
if (sqlite3_step(stmt) != SQLITE_DONE) {
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
+ return 1;
}
sqlite3_finalize(stmt);
provided = provided->next;
@@ -279,6 +324,7 @@ generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
currpackage->sourceheader->id);
if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
+ return 1;
}
sqlite3_bind_text(stmt, 1, currpackage->name, -1, SQLITE_STATIC);
@@ -543,8 +589,8 @@ generateSQLite(struct configTag *ct)
return 1;
}
- generateSQLite_packages(ct, db, i);
- generateSQLite_provided(ct, db, i);
+ if (generateSQLite_packages(ct, db, i)) return 1;
+ if (generateSQLite_provided(ct, db, i)) return 1;
sqlite3_close(db);
}
diff --git a/src/distromatic.c b/src/distromatic.c
index 4fba577..4904abb 100644
--- a/src/distromatic.c
+++ b/src/distromatic.c
@@ -1203,10 +1203,10 @@ main(int argc, char *argv[])
} // if (genheader_mode)
if (mode & MODE_SQLITE3) {
- if (!quietmode) printf("Generating sqlite3 databases...\n");
+ if (!quietmode) printf("Generating SQLite databases...\n");
logmsg(LOG_DEBUG,"generateSQLite3 - start");
if (generateSQLite(configtag)) {
- logmsg(LOG_ERROR, "could not generate sqlite3 databases; aborting.");
+ logmsg(LOG_ERROR, "could not generate SQLite databases; aborting.");
exit(1);
}
logmsg(LOG_DEBUG,"generateSQLite3 - done");
diff --git a/src/distroquery.c b/src/distroquery.c
index f2d342b..2c2fc0f 100644
--- a/src/distroquery.c
+++ b/src/distroquery.c
@@ -190,6 +190,26 @@ void printTagsLine(const char* arch, const char* tag, const char* group, const c
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;
@@ -732,15 +752,23 @@ void printPackageData() {
/* 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 WHERE name='%s'", query_package);
+ 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(" %s
", resolveFilePath(dbf, sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "id_file")), buffer));
+ printf("%s | %s | %s | %s |
",
+ 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("
");
}
sqlite3_close(dbs);
}
diff --git a/src/functions.c b/src/functions.c
index 6b3f3d6..3adff94 100644
--- a/src/functions.c
+++ b/src/functions.c
@@ -153,7 +153,7 @@ struct configTag* read_configuration(const char *confFile)
} else {
configsection = CONF_REP_SECTION;
- newconfigtag = malloc(sizeof(struct configTag));
+ newconfigtag = calloc(1, sizeof(struct configTag));
if (!newconfigtag) {
fprintf(stderr, "The system is out of memory\n");
return NULL;
@@ -161,23 +161,11 @@ struct configTag* read_configuration(const char *confFile)
newconfigtag->tag =
(char *) strndup(&vartok[1], strlen(vartok) - 2);
- newconfigtag->repository_dir = NULL;
- newconfigtag->repository_source_dir = NULL;
curraltrep = 0;
- for (i = 0; irepository[i] = NULL;
- newconfigtag->html_dir = NULL;
- newconfigtag->download_prefix = NULL;
- newconfigtag->download_dir = NULL;
- newconfigtag->showfile_prefix = NULL;
for (i = 0; iarch[i] = configdefaults.arch[i];
- newconfigtag->headerlist[i] = NULL;
- newconfigtag->filetree[i]=NULL;
- for (j = 0; jprovidedlist_idx[i][j]=NULL;
}
newconfigtag->configdefaults = &configdefaults;
- newconfigtag->headersourcelist = NULL;
if (configdefaults.html_basedir) {
strncpy(buf, configdefaults.html_basedir, PATH_MAX);
diff --git a/src/headerlist.c b/src/headerlist.c
index fc22c70..99fe191 100644
--- a/src/headerlist.c
+++ b/src/headerlist.c
@@ -502,6 +502,7 @@ findOrCreateFileTreeBrother(struct fileTree* *first,char* findname, int arch)
return currdir;
}
+
struct fileTree*
findOrCreateFileTreeEntry(struct fileTree* *first,char* findname, int arch)
{
@@ -539,6 +540,48 @@ findOrCreateFileTreeEntry(struct fileTree* *first,char* findname, int arch)
return currdir;
}
+struct fileUserList*
+findOrCreateFileUserListEntry(struct fileUserList* *first,char* name, int arch)
+{
+ static long id[ARCHS_MAX] = { 0, 0, 0, 0, 0 };
+ struct fileUserList *curr = *first, *prev = NULL, *newf = NULL;
+ int i;
+
+ while (curr && (i=strcmp(curr->name,name)) < 0) {
+ prev = curr;
+ curr = curr->next;
+ }
+ if (curr && (i == 0)) return curr;
+ newf = malloc(sizeof(struct fileUserList));
+ newf->name = strdup(name);
+ newf->id = ++id[arch];
+ if (prev) prev->next = newf; else *first = newf;
+ if (curr) newf->next = curr; else newf->next = NULL;
+ if (!*first) *first = newf;
+ return newf;
+}
+
+struct fileGroupList*
+findOrCreateFileGroupListEntry(struct fileGroupList* *first,char* name, int arch)
+{
+ static long id[ARCHS_MAX] = { 0, 0, 0, 0, 0 };
+ struct fileGroupList *curr = *first, *prev = NULL, *newf = NULL;
+ int i;
+
+ while (curr && ((i=strcmp(curr->name,name)) < 0)) {
+ prev = curr;
+ curr = curr->next;
+ }
+ if (curr && (i == 0)) return curr;
+ newf = malloc(sizeof(struct fileGroupList));
+ newf->name = strdup(name);
+ newf->id = ++id[arch];
+ if (prev) prev->next = newf; else *first = newf;
+ if (curr) newf->next = curr; else newf->next = NULL;
+ if (!*first) *first = newf;
+ return newf;
+}
+
static long sourceid = 0;
int
@@ -553,7 +596,8 @@ addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configT
Header h;
char filepath[bufsize + 1];
int n, j, arch, *dirindexes, filenamescount, dirnamescount;
- char **basenames, **dirnames;
+ int_16 *fileflags;
+ char **basenames, **dirnames, **usernames, **groupnames;
const char* errstr;
int requirecount;
char **requireversion, **requirename;
@@ -602,8 +646,9 @@ addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configT
"%s: unable to read header (%s); skipping.",namelist[cnt]->d_name, errstr);
} else {
- getPackageFilenames(h, &dirindexes, &dirnames, &dirnamescount,
- &basenames, &filenamescount);
+ getPackageFiles(h, &dirindexes, &dirnames, &dirnamescount,
+ &basenames, &filenamescount,
+ &usernames, &groupnames, &fileflags);
newheadersourcelist =
malloc(sizeof(struct headerSourceList));
@@ -797,11 +842,14 @@ addToHeaderList(struct configTag *ct,
char *filename=NULL;
long i ,j , k, n, altn[ALT_REPS_MAX];
int altrepository=0, obsoletecount, providecount, requirecount,
- filenamecount, dirnamecount, *dirindex;
+ filenamecount, dirnamecount,
+ *dirindex;
+ int_16 *fileflags;
char **obsoletename, **obsoleteversion,
**providename, **provideversion,
**requirename, **requireversion,
- **basename, **dirname, **newversion;
+ **basename, **dirname, **newversion,
+ **fileusername, **filegroupname;
const char* errstr;
uint_32 *requireflags, *obsoleteflags, *provideflags;
#if RPM_VERSION >= 0x040100
@@ -915,8 +963,9 @@ addToHeaderList(struct configTag *ct,
&provideversion, &providecount);
getPackageRequires(h, &requirename, &requireflags,
&requireversion, &requirecount);
- getPackageFilenames(h, &dirindex, &dirname, &dirnamecount,
- &basename, &filenamecount);
+ getPackageFiles(h, &dirindex, &dirname, &dirnamecount,
+ &basename, &filenamecount,
+ &fileusername, &filegroupname, &fileflags);
newheaderlist = malloc(sizeof(struct headerList));
if (newheaderlist == NULL) {
@@ -1052,9 +1101,20 @@ addToHeaderList(struct configTag *ct,
newheaderlist->file =
malloc(sizeof(struct fileTree*) * filenamecount);
+ newheaderlist->fileflags =
+ malloc(sizeof(int_16 *) * filenamecount);
+ newheaderlist->fileuser =
+ malloc(sizeof(struct fileUserList *) * filenamecount);
+ newheaderlist->filegroup =
+ malloc(sizeof(char *) * filenamecount);
for (j=0; jfile[j] = findOrCreateFileTreeEntry(&ct->filetree[arch],filename,arch);
+ newheaderlist->file[j] = findOrCreateFileTreeEntry(&ct->filetree[arch], filename, arch);
+ newheaderlist->fileflags[j] = fileflags[j];
+ newheaderlist->fileuser[j] = findOrCreateFileUserListEntry(&ct->fileuserlist[arch], fileusername[j], arch);
+ free(fileusername[j]);
+ newheaderlist->filegroup[j] = findOrCreateFileGroupListEntry(&ct->filegrouplist[arch], filegroupname[j], arch);
+ free(filegroupname[j]);
if (newheaderlist->file[j]->numproviders == 0) {
newheaderlist->file[j]->numproviders++;
newheaderlist->file[j]->provider=malloc(sizeof(struct headerList*));
diff --git a/src/include/distromatic.h b/src/include/distromatic.h
index 6856ce5..cc7c081 100644
--- a/src/include/distromatic.h
+++ b/src/include/distromatic.h
@@ -37,6 +37,8 @@ struct configTag {
struct headerSourceList *headersourcelist;
struct providedList *providedlist_idx[ARCHS_MAX][PROVIDEDLIST_IDX_SIZE];
struct fileTree *filetree[ARCHS_MAX];
+ struct fileUserList *fileuserlist[ARCHS_MAX];
+ struct fileGroupList *filegrouplist[ARCHS_MAX];
struct headerStats stats;
struct configTag *next;
void *db[ARCHS_MAX + 1];
diff --git a/src/include/headerlist.h b/src/include/headerlist.h
index ad2c534..d50a71a 100644
--- a/src/include/headerlist.h
+++ b/src/include/headerlist.h
@@ -44,6 +44,18 @@ struct fileTree {
long id;
};
+struct fileUserList {
+ char *name;
+ struct fileUserList* next;
+ long id;
+};
+
+struct fileGroupList {
+ char *name;
+ struct fileGroupList* next;
+ long id;
+};
+
struct warningList {
char* text;
struct warningList *next;
@@ -81,6 +93,9 @@ struct headerList {
struct providedList **provided;
int filenamecount;
struct fileTree **file;
+ int_16 *fileflags;
+ struct fileUserList **fileuser;
+ struct fileGroupList **filegroup;
int recursed;
struct requireList *requirelist;
struct headerList *next, *nextbrother;
diff --git a/src/include/rpmfunctions.h b/src/include/rpmfunctions.h
index 974bf35..11f004d 100644
--- a/src/include/rpmfunctions.h
+++ b/src/include/rpmfunctions.h
@@ -45,10 +45,12 @@ int getPackageObsoletes(
Header h, char ***obsoletename, uint_32 **obsoleteflags,
char ***obsoleteversion, int *obsoletecount);
-int getPackageFilenames(
- Header h, int **dirindexes,
- char ***dirnames, int *dirnamescount,
- char ***basenames, int *filenamescount);
+int
+getPackageFiles(Header h, int **dirindexes,
+ char ***dirnames, int *dirnamescount,
+ char ***basenames, int *filenamescount,
+ char ***usernames, char ***groupnames,
+ int_16 **fileflags);
int rpmnamecmp(char *filename1, char *filename2, int checkver);
diff --git a/src/rpmfunctions.c b/src/rpmfunctions.c
index 99675ae..8da5849 100644
--- a/src/rpmfunctions.c
+++ b/src/rpmfunctions.c
@@ -201,7 +201,7 @@ long long headerGetUIntEntry(Header h, const int tag) {
break;
case RPM_UINT32_TYPE:
ret = *he->p.ui32p;
- break;
+ break;
case RPM_UINT64_TYPE:
ret = *he->p.ui64p;
break;
@@ -227,20 +227,20 @@ void *headerGetUIntArrayEntry(Header h, const int tag, int *count) {
*count = he->c;
switch (he->t) {
case RPM_UINT8_TYPE:
- ret = memndup(he->p.ui8p, he->c * sizeof(he->p.ui8p));
+ ret = memndup(he->p.ui8p, *count);
break;
case RPM_UINT16_TYPE:
- ret = memndup(he->p.ui16p, he->c * sizeof(he->p.ui16p));
+ ret = memndup(he->p.ui16p, *count * 2);
break;
case RPM_UINT32_TYPE:
- ret = memndup(he->p.ui32p, he->c * sizeof(he->p.ui32p));
+ ret = memndup(he->p.ui32p, *count * 4);
//int i;
//for (i=0; ic; i++) {
// printf("%d ",((int_32 *)ret)[i]);
//}
- break;
+ break;
case RPM_UINT64_TYPE:
- ret = memndup(he->p.ui64p, he->c * sizeof(he->p.ui64p));
+ ret = memndup(he->p.ui64p, *count * 8);
break;
default:
ret = NULL;
@@ -248,10 +248,10 @@ void *headerGetUIntArrayEntry(Header h, const int tag, int *count) {
}
}
-//unsigned int i;
-//for (i=0; i < he->c; i++) {
-//fprintf(stderr," headerGetUIntArrayEntry tag:%d value:%ld\n", he->tag, ((rpmuint32_t*)ret)[i]);
-//}
+/*unsigned int i;
+for (i=0; i < he->c; i++) {
+fprintf(stderr," headerGetUIntArrayEntry tag:%d value:%ld\n", he->tag, ((rpmuint32_t*)ret)[i]);
+}*/
he->p.ptr = _free(he->p.ptr);
return ret;
}
@@ -290,9 +290,11 @@ getPackageObsoletes(Header h, char ***obsoletename, uint_32 **obsoleteflags,
}
int
-getPackageFilenames(Header h, int **dirindexes,
+getPackageFiles(Header h, int **dirindexes,
char ***dirnames, int *dirnamescount,
- char ***basenames, int *filenamescount)
+ char ***basenames, int *filenamescount,
+ char ***usernames, char ***groupnames,
+ int_16 **fileflags)
{
int count;
@@ -300,6 +302,9 @@ getPackageFilenames(Header h, int **dirindexes,
*dirindexes = headerGetUIntArrayEntry(h, RPMTAG_DIRINDEXES, &count);
*dirnames = headerGetStringArrayEntry(h, RPMTAG_DIRNAMES, dirnamescount);
*basenames = headerGetStringArrayEntry(h, RPMTAG_BASENAMES, filenamescount);
+ *usernames = headerGetStringArrayEntry(h, RPMTAG_FILEUSERNAME, &count);
+ *groupnames = headerGetStringArrayEntry(h, RPMTAG_FILEGROUPNAME, &count);
+ *fileflags = headerGetUIntArrayEntry(h, RPMTAG_FILEMODES, &count);
return 0;
}