From af4a56a06a9e347737077217c37cfdb6c411a6df Mon Sep 17 00:00:00 2001 From: KOLANICH Date: Thu, 23 Jul 2020 16:37:06 +0300 Subject: [PATCH] Added passing the needed info through an environment variable in bencode serialization. Can be further extended, if we need more info. --- src/archives.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++- src/main.h | 19 ++++++++- src/unpack.c | 32 ++++++++++++++- 3 files changed, 153 insertions(+), 3 deletions(-) diff --git a/src/archives.c b/src/archives.c index ee1ae51ed..ea9e7a607 100644 --- a/src/archives.c +++ b/src/archives.c @@ -1464,6 +1464,106 @@ void cu_fileslist(int argc, void **argv) { tar_pool_release(); } +static struct passed_through_package_info passed_through_package_info_init(){ + struct passed_through_package_info unpackedInfo; + unpackedInfo.count = 0; + unpackedInfo.records = NULL; + return unpackedInfo; +} + +static void free_pascal_string(struct pascal_str *str){ + free(str->ptr); + str->ptr = NULL; + str->size = 0; +} + +static void free_passed_through_package_info_record(struct passed_through_package_info_record *r){ + free_pascal_string(&r->name); + free_pascal_string(&r->arch); + free_pascal_string(&r->version); +} + +static void passed_through_package_info_free(struct passed_through_package_info *unpackedInfo){ + for(unsigned short int i = 0; i< unpackedInfo->count; ++i){ + free_passed_through_package_info_record(&unpackedInfo->records[i]); + } + free(unpackedInfo->records); + unpackedInfo->records = NULL; + unpackedInfo->count = 0; +} + +static size_t measure_benc_pascal_str(struct pascal_str *s){ + return snprintf(NULL, 0, "%zu:", s->size) + s->size; +} + +static void serialize_benc_pascal_str(char **serPtr, struct pascal_str *s){ + *serPtr += sprintf(*serPtr, "%zu:%s", s->size, s->ptr); +} +static void serialize_benc_tag(char **serPtr, char tag){ + *serPtr += sprintf(*serPtr, "1:%c", tag); +} + +static void serialize_benc_tag_value_pair(char **serPtr, char tag, struct pascal_str *s){ + if(s->ptr){ + serialize_benc_tag(serPtr, tag); + serialize_benc_pascal_str(serPtr, s); + } +} + +enum { + OUR_BENC_KEY_TAG_SIZE = 3, + BENC_START_END = 2, // l<...>e +}; + +static size_t measure_benc_tag_value_pair(struct pascal_str *s){ + if(s->ptr){ + return measure_benc_pascal_str(s) + OUR_BENC_KEY_TAG_SIZE; + } else { + return 0; + } +} + + +static size_t precompute_the_bencode_serialized_size(struct passed_through_package_info *unpackedInfo){ + size_t totalSize = BENC_START_END; + int i; + for(i=0;icount;++i){ + if(unpackedInfo->records[i].name.size){ + totalSize += measure_benc_pascal_str(&unpackedInfo->records[i].name); + totalSize += BENC_START_END; + totalSize += measure_benc_tag_value_pair(&unpackedInfo->records[i].arch); + totalSize += measure_benc_tag_value_pair(&unpackedInfo->records[i].version); + totalSize += measure_benc_tag_value_pair(&unpackedInfo->records[i].origin); + } + } + totalSize ++; // null termination + return totalSize; +} + +static void serialize_the_info_about_triggerers_into_an_env_variable(struct passed_through_package_info *unpackedInfo){ + unsigned int i; + size_t totalSize = precompute_the_bencode_serialized_size(unpackedInfo); + char buf4str[totalSize]; + + memset(buf4str, ' ', totalSize); + buf4str[totalSize - 1] = 0; + char * serPtr = &buf4str[0]; + *(serPtr++) = 'd'; + for(i=0;icount;++i){ + serialize_benc_pascal_str(&serPtr, &unpackedInfo->records[i].name); + *(serPtr++) = 'd'; + serialize_benc_tag_value_pair(&serPtr, 'A', &unpackedInfo->records[i].arch); + serialize_benc_tag_value_pair(&serPtr, 'V', &unpackedInfo->records[i].version); + serialize_benc_tag_value_pair(&serPtr, 'O', &unpackedInfo->records[i].origin); + *(serPtr++) = 'e'; + } + *(serPtr++) = 'e'; + if((unsigned long)((char*) serPtr - (char*) buf4str) > totalSize){ + ohshit("Buffer overflow %zu > %zu !", (char*) serPtr - (char*) buf4str, totalSize); + } + setenv("DPKG_TRIGGERER_PACKAGES_INFO", buf4str, 1); +} + int archivefiles(const char *const *argv) { @@ -1472,6 +1572,7 @@ archivefiles(const char *const *argv) int i; jmp_buf ejbuf; enum modstatdb_rw msdbflags; + struct passed_through_package_info unpackedInfo = passed_through_package_info_init(); trigproc_install_hooks(); @@ -1574,7 +1675,7 @@ archivefiles(const char *const *argv) dpkg_selabel_load(); - process_archive(argp[i]); + process_archive(argp[i], &unpackedInfo); onerr_abort++; m_output(stdout, _("")); m_output(stderr, _("")); @@ -1582,6 +1683,8 @@ archivefiles(const char *const *argv) pop_error_context(ehflag_normaltidy); } + serialize_the_info_about_triggerers_into_an_env_variable(&unpackedInfo); + passed_through_package_info_free(&unpackedInfo); dpkg_selabel_close(); diff --git a/src/main.h b/src/main.h index e7fe820a7..70fe47d92 100644 --- a/src/main.h +++ b/src/main.h @@ -142,6 +142,23 @@ struct invoke_list { struct invoke_hook *head, **tail; }; +struct pascal_str { + size_t size; + char * ptr; +}; + +struct passed_through_package_info_record { + struct pascal_str name; + struct pascal_str arch; + struct pascal_str version; + struct pascal_str origin; +}; + +struct passed_through_package_info{ + unsigned int count; + struct passed_through_package_info_record *records; +}; + /* from perpkgstate.c */ void ensure_package_clientdata(struct pkginfo *pkg); @@ -149,7 +166,7 @@ void ensure_package_clientdata(struct pkginfo *pkg); /* from archives.c */ int archivefiles(const char *const *argv); -void process_archive(const char *filename); +void process_archive(const char *filename, struct passed_through_package_info *unpackedInfo); bool wanttoinstall(struct pkginfo *pkg); /* from update.c */ diff --git a/src/unpack.c b/src/unpack.c index 4a143666e..f6a716d11 100644 --- a/src/unpack.c +++ b/src/unpack.c @@ -1064,7 +1064,36 @@ pkg_remove_backup_files(struct pkginfo *pkg, struct fsys_namenode_list *newfiles } } -void process_archive(const char *filename) { + +struct pascal_str init_pascal_str(char * s){ + struct pascal_str res; + if(s){ + res.size = strlen(s); + res.ptr = malloc(res.size + 1); + strcpy(res.ptr, s); + }else{ + res.size = 0; + res.ptr = NULL; + } + return res; +} + + +void passed_through_package_info_append(struct passed_through_package_info *unpackedInfo, struct pkginfo *pkg){ + struct passed_through_package_info_record * rec; + unsigned int prevCountAndIndex = unpackedInfo->count; + unpackedInfo->records = realloc(unpackedInfo->records, sizeof(struct passed_through_package_info_record) * (++unpackedInfo->count)); + if(!unpackedInfo->records){ + ohshite(_("Unable to reallocate in %s"), __func__); + } + rec = &(unpackedInfo->records[prevCountAndIndex]); + rec->name = init_pascal_str(pkg->set->name); + rec->version = init_pascal_str(pkg->available.version.version); + rec->arch = init_pascal_str(pkg->available.arch->name); + rec->origin = init_pascal_str(pkg->available.origin); +} + +void process_archive(const char *filename, struct passed_through_package_info *unpackedInfo) { static const struct tar_operations tf = { .read = tarfileread, .extract_file = tarobject, @@ -1146,6 +1175,7 @@ void process_archive(const char *filename) { parsedb(cidir, parsedb_flags, &pkg); + passed_through_package_info_append(unpackedInfo, pkg); if (!pkg->archives) { pkg->archives = nfmalloc(sizeof(*pkg->archives)); pkg->archives->next = NULL;