Last active
January 7, 2019 16:08
-
-
Save igor-raits/e4d554c2a2263681f90c971adaf930e9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <locale.h> | |
| #include <stdbool.h> | |
| #include <glib.h> | |
| #include <libsmartcols.h> | |
| #include <solv/pool.h> | |
| #include <solv/repo.h> | |
| #include <solv/repo_solv.h> | |
| #include <json-glib/json-glib.h> | |
| #include <libsoup/soup.h> | |
| enum { | |
| COL_NAME, | |
| COL_MAINTAINERS, | |
| COL_NOTES, | |
| }; | |
| static inline char * | |
| join_keys (GHashTable *hash_table, | |
| const char *separator) | |
| { | |
| unsigned int length = 0; | |
| g_autofree char **strv = (char **)g_hash_table_get_keys_as_array (hash_table, &length); | |
| return g_strjoinv (separator, strv); | |
| } | |
| int | |
| main (void) | |
| { | |
| struct libscols_table *tb; | |
| struct libscols_column *cl; | |
| struct libscols_line *ln; | |
| FILE *fp; | |
| Queue q; | |
| g_autoptr(GError) err = NULL; | |
| setlocale (LC_ALL, ""); | |
| Pool *pool = pool_create (); | |
| //pool_setdebuglevel (pool, 10); | |
| //scols_init_debug (0xffff); | |
| Repo *repo = repo_create (pool, "rawhide"); | |
| fp = fopen ("/var/cache/dnf/rawhide.solv", "rb"); | |
| repo_add_solv (repo, fp, 0); | |
| fclose (fp); | |
| Repodata *repodata = repo_add_repodata (repo, 0); | |
| repodata_extend_block (repodata, repo->start, repo->end - repo->start); | |
| fp = fopen ("/var/cache/dnf/rawhide-filenames.solvx", "rb"); | |
| repodata->state = REPODATA_LOADING; | |
| repo_add_solv (repo, fp, REPO_USE_LOADING | REPO_EXTEND_SOLVABLES | REPO_LOCALPOOL); | |
| repodata->state = REPODATA_AVAILABLE; | |
| fclose (fp); | |
| repodata_internalize (repodata); | |
| pool_addfileprovides (pool); | |
| pool_createwhatprovides (pool); | |
| /* pkg → [err…] */ | |
| g_autoptr(GHashTable) to_fix = g_hash_table_new_full (g_str_hash, | |
| g_str_equal, | |
| g_free, | |
| (GDestroyNotify)g_hash_table_unref); | |
| /* src → [pkg…] */ | |
| g_autoptr(GHashTable) smap = g_hash_table_new_full (g_str_hash, | |
| g_str_equal, | |
| g_free, | |
| (GDestroyNotify)g_hash_table_unref); | |
| g_autoptr(JsonParser) json = json_parser_new_immutable (); | |
| #if 0 | |
| g_autoptr(SoupSession) soup = soup_session_new (); | |
| g_autoptr(SoupMessage) msg = soup_message_new ("GET", "https://src.fedoraproject.org/extras/pagure_owner_alias.json"); | |
| g_autoptr(GInputStream) stream = soup_session_send (soup, msg, NULL, &err); | |
| #else | |
| g_autoptr(GFile) file = g_file_new_for_path ("/var/tmp/pagure_owner_alias.json"); | |
| g_autoptr(GInputStream) stream = (GInputStream *)g_file_read (file, NULL, &err); | |
| #endif | |
| if (!stream) | |
| goto err; | |
| if (!json_parser_load_from_stream (json, stream, NULL, &err)) | |
| goto err; | |
| JsonObject *root = json_node_get_object (json_parser_get_root (json)); | |
| JsonObject *owners = json_object_get_object_member (root, "rpms"); | |
| queue_init (&q); | |
| pool_whatmatchesdep (pool, | |
| SOLVABLE_REQUIRES, | |
| pool_str2id (pool, | |
| "/sbin/ldconfig", | |
| 1), | |
| &q, | |
| 0); | |
| for (int i = 0; i < q.count; i++) | |
| { | |
| Id p = q.elements[i]; | |
| Solvable *s = pool_id2solvable (pool, p); | |
| Dataiterator di; | |
| dataiterator_init (&di, pool, 0, p, SOLVABLE_FILELIST, "/etc/ld.so.conf.d/*", SEARCH_FILES | SEARCH_GLOB); | |
| if (dataiterator_step (&di)) | |
| { | |
| dataiterator_free (&di); | |
| continue; | |
| } | |
| dataiterator_free (&di); | |
| const char *name = pool_id2str (pool, s->name); | |
| GHashTable *errors = g_hash_table_lookup (to_fix, name); | |
| if (!errors) | |
| { | |
| errors = g_hash_table_new (g_str_hash, g_str_equal); | |
| g_hash_table_insert (to_fix, g_strdup (name), errors); | |
| } | |
| g_hash_table_add (errors, "Uneeded /sbin/ldconfig"); | |
| const char *srcname; | |
| if (solvable_lookup_void(s, SOLVABLE_SOURCENAME)) | |
| srcname = pool_id2str (pool, s->name); | |
| else | |
| srcname = solvable_lookup_str (s, SOLVABLE_SOURCENAME); | |
| GHashTable *subpkgs = g_hash_table_lookup (smap, srcname); | |
| if (!subpkgs) | |
| { | |
| subpkgs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); | |
| g_hash_table_insert (smap, g_strdup (srcname), subpkgs); | |
| } | |
| g_hash_table_add (subpkgs, g_strdup (name)); | |
| } | |
| queue_free (&q); | |
| tb = scols_new_table (); | |
| cl =scols_table_new_column (tb, "NAME", 0, SCOLS_FL_TREE); | |
| scols_column_set_cmpfunc (cl, scols_cmpstr_cells, NULL); | |
| cl = scols_table_new_column (tb, "MAINTAINERS", 0, SCOLS_FL_WRAP | SCOLS_FL_NOEXTREMES); | |
| scols_column_set_wrapfunc (cl, | |
| scols_wrapnl_chunksize, | |
| scols_wrapnl_nextchunk, | |
| NULL); | |
| scols_column_set_safechars (cl, "\n"); | |
| cl = scols_table_new_column (tb, "NOTES", 0, SCOLS_FL_WRAP); | |
| scols_column_set_wrapfunc (cl, | |
| scols_wrapnl_chunksize, | |
| scols_wrapnl_nextchunk, | |
| NULL); | |
| scols_column_set_safechars (cl, "\n"); | |
| GHashTableIter iter; | |
| g_hash_table_iter_init (&iter, smap); | |
| gpointer key, value; | |
| while (g_hash_table_iter_next (&iter, &key, &value)) | |
| { | |
| const char *srcname = key; | |
| ln = scols_table_new_line (tb, NULL); | |
| scols_line_set_data (ln, COL_NAME, srcname); | |
| JsonArray *owners_array = json_object_get_array_member (owners, srcname); | |
| g_autoptr(GList) pkg_owners = NULL; | |
| for (int i = 0; i < json_array_get_length (owners_array); i++) | |
| /* It is fine to discard const here because we are not going | |
| * to free that data and it is not going to outlive. */ | |
| pkg_owners = g_list_insert_sorted (pkg_owners, | |
| (char *)json_array_get_string_element (owners_array, i), | |
| (GCompareFunc)g_strcmp0); | |
| pkg_owners = g_list_first (pkg_owners); | |
| g_autoptr(GString) maintainers = g_string_new (pkg_owners->data); | |
| for (GList *owner = pkg_owners->next; owner; owner = owner->next) | |
| g_string_append_printf (maintainers, "\n%s", (const char *)owner->data); | |
| scols_line_set_data (ln, COL_MAINTAINERS, maintainers->str); | |
| GHashTable *subpkgs = value; | |
| GHashTableIter siter; | |
| g_hash_table_iter_init (&siter, subpkgs); | |
| while (g_hash_table_iter_next (&siter, &key, &value)) | |
| { | |
| const char *name = key; | |
| GHashTable *errors = g_hash_table_lookup (to_fix, name); | |
| g_autofree char *notes = join_keys (errors, "\n"); | |
| struct libscols_line *xln = scols_table_new_line (tb, ln); | |
| scols_line_set_data (xln, COL_NAME, name); | |
| scols_line_set_data (xln, COL_NOTES, notes); | |
| } | |
| } | |
| scols_sort_table (tb, scols_table_get_column (tb, COL_NAME)); | |
| scols_print_table (tb); | |
| scols_unref_table (tb); | |
| err: | |
| if (err) | |
| printf ("%s\n", err->message); | |
| pool_free (pool); | |
| return EXIT_SUCCESS; | |
| } | |
| #include <locale.h> | |
| #include <stdbool.h> | |
| #include <glib.h> | |
| #include <libsmartcols.h> | |
| #include <solv/pool.h> | |
| #include <solv/repo.h> | |
| #include <solv/repo_solv.h> | |
| #include <json-glib/json-glib.h> | |
| #include <libsoup/soup.h> | |
| enum { | |
| COL_NAME, | |
| COL_MAINTAINERS, | |
| COL_NOTES, | |
| }; | |
| static inline char * | |
| join_keys (GHashTable *hash_table, | |
| const char *separator) | |
| { | |
| unsigned int length = 0; | |
| g_autofree char **strv = (char **)g_hash_table_get_keys_as_array (hash_table, &length); | |
| return g_strjoinv (separator, strv); | |
| } | |
| int | |
| main (void) | |
| { | |
| struct libscols_table *tb; | |
| struct libscols_column *cl; | |
| struct libscols_line *ln; | |
| FILE *fp; | |
| Queue q; | |
| g_autoptr(GError) err = NULL; | |
| setlocale (LC_ALL, ""); | |
| Pool *pool = pool_create (); | |
| //pool_setdebuglevel (pool, 10); | |
| scols_init_debug (0xffff); | |
| Repo *repo = repo_create (pool, "rawhide"); | |
| fp = fopen ("/var/cache/dnf/rawhide.solv", "rb"); | |
| repo_add_solv (repo, fp, 0); | |
| fclose (fp); | |
| Repodata *repodata = repo_add_repodata (repo, 0); | |
| repodata_extend_block (repodata, repo->start, repo->end - repo->start); | |
| fp = fopen ("/var/cache/dnf/rawhide-filenames.solvx", "rb"); | |
| repodata->state = REPODATA_LOADING; | |
| repo_add_solv (repo, fp, REPO_USE_LOADING | REPO_EXTEND_SOLVABLES | REPO_LOCALPOOL); | |
| repodata->state = REPODATA_AVAILABLE; | |
| fclose (fp); | |
| repodata_internalize (repodata); | |
| pool_addfileprovides (pool); | |
| pool_createwhatprovides (pool); | |
| /* pkg → [err…] */ | |
| g_autoptr(GHashTable) to_fix = g_hash_table_new_full (g_str_hash, | |
| g_str_equal, | |
| g_free, | |
| (GDestroyNotify)g_hash_table_unref); | |
| /* src → [pkg…] */ | |
| g_autoptr(GHashTable) smap = g_hash_table_new_full (g_str_hash, | |
| g_str_equal, | |
| g_free, | |
| (GDestroyNotify)g_hash_table_unref); | |
| g_autoptr(JsonParser) json = json_parser_new_immutable (); | |
| #if 0 | |
| g_autoptr(SoupSession) soup = soup_session_new (); | |
| g_autoptr(SoupMessage) msg = soup_message_new ("GET", "https://src.fedoraproject.org/extras/pagure_owner_alias.json"); | |
| g_autoptr(GInputStream) stream = soup_session_send (soup, msg, NULL, &err); | |
| #else | |
| g_autoptr(GFile) file = g_file_new_for_path ("/var/tmp/pagure_owner_alias.json"); | |
| g_autoptr(GInputStream) stream = (GInputStream *)g_file_read (file, NULL, &err); | |
| #endif | |
| if (!stream) | |
| goto err; | |
| if (!json_parser_load_from_stream (json, stream, NULL, &err)) | |
| goto err; | |
| JsonObject *root = json_node_get_object (json_parser_get_root (json)); | |
| JsonObject *owners = json_object_get_object_member (root, "rpms"); | |
| queue_init (&q); | |
| pool_whatmatchesdep (pool, | |
| SOLVABLE_REQUIRES, | |
| pool_str2id (pool, | |
| "/sbin/ldconfig", | |
| 1), | |
| &q, | |
| 0); | |
| for (int i = 0; i < q.count; i++) | |
| { | |
| Id p = q.elements[i]; | |
| Solvable *s = pool_id2solvable (pool, p); | |
| Dataiterator di; | |
| dataiterator_init (&di, pool, 0, p, SOLVABLE_FILELIST, "/etc/ld.so.conf.d/*", SEARCH_FILES | SEARCH_GLOB); | |
| if (dataiterator_step (&di)) | |
| { | |
| dataiterator_free (&di); | |
| continue; | |
| } | |
| dataiterator_free (&di); | |
| const char *name = pool_id2str (pool, s->name); | |
| GHashTable *errors = g_hash_table_lookup (to_fix, name); | |
| if (!errors) | |
| { | |
| errors = g_hash_table_new (g_str_hash, g_str_equal); | |
| g_hash_table_insert (to_fix, g_strdup (name), errors); | |
| } | |
| g_hash_table_add (errors, "Uneeded /sbin/ldconfig"); | |
| const char *srcname; | |
| if (solvable_lookup_void(s, SOLVABLE_SOURCENAME)) | |
| srcname = pool_id2str (pool, s->name); | |
| else | |
| srcname = solvable_lookup_str (s, SOLVABLE_SOURCENAME); | |
| GHashTable *subpkgs = g_hash_table_lookup (smap, srcname); | |
| if (!subpkgs) | |
| { | |
| subpkgs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); | |
| g_hash_table_insert (smap, g_strdup (srcname), subpkgs); | |
| } | |
| g_hash_table_add (subpkgs, g_strdup (name)); | |
| } | |
| queue_free (&q); | |
| tb = scols_new_table (); | |
| cl =scols_table_new_column (tb, "NAME", 0, SCOLS_FL_TREE); | |
| scols_column_set_cmpfunc (cl, scols_cmpstr_cells, NULL); | |
| cl = scols_table_new_column (tb, "MAINTAINERS", 0, SCOLS_FL_WRAP | SCOLS_FL_NOEXTREMES); | |
| scols_column_set_wrapfunc (cl, | |
| scols_wrapnl_chunksize, | |
| scols_wrapnl_nextchunk, | |
| NULL); | |
| scols_column_set_safechars (cl, "\n"); | |
| cl = scols_table_new_column (tb, "NOTES", 0, SCOLS_FL_WRAP); | |
| scols_column_set_wrapfunc (cl, | |
| scols_wrapnl_chunksize, | |
| scols_wrapnl_nextchunk, | |
| NULL); | |
| scols_column_set_safechars (cl, "\n"); | |
| GHashTableIter iter; | |
| g_hash_table_iter_init (&iter, smap); | |
| gpointer key, value; | |
| while (g_hash_table_iter_next (&iter, &key, &value)) | |
| { | |
| const char *srcname = key; | |
| ln = scols_table_new_line (tb, NULL); | |
| scols_line_set_data (ln, COL_NAME, srcname); | |
| JsonArray *owners_array = json_object_get_array_member (owners, srcname); | |
| g_autoptr(GList) pkg_owners = NULL; | |
| for (int i = 0; i < json_array_get_length (owners_array); i++) | |
| /* It is fine to discard const here because we are not going | |
| * to free that data and it is not going to outlive. */ | |
| pkg_owners = g_list_insert_sorted (pkg_owners, | |
| (char *)json_array_get_string_element (owners_array, i), | |
| (GCompareFunc)g_strcmp0); | |
| pkg_owners = g_list_first (pkg_owners); | |
| g_autoptr(GString) maintainers = g_string_new (pkg_owners->data); | |
| for (GList *owner = pkg_owners->next; owner; owner = owner->next) | |
| g_string_append_printf (maintainers, "\n%s", (const char *)owner->data); | |
| scols_line_set_data (ln, COL_MAINTAINERS, maintainers->str); | |
| GHashTable *subpkgs = value; | |
| GHashTableIter siter; | |
| g_hash_table_iter_init (&siter, subpkgs); | |
| while (g_hash_table_iter_next (&siter, &key, &value)) | |
| { | |
| const char *name = key; | |
| GHashTable *errors = g_hash_table_lookup (to_fix, name); | |
| g_autofree char *notes = join_keys (errors, "\n"); | |
| struct libscols_line *xln = scols_table_new_line (tb, ln); | |
| scols_line_set_data (xln, COL_NAME, name); | |
| scols_line_set_data (xln, COL_NOTES, notes); | |
| } | |
| } | |
| scols_sort_table (tb, scols_table_get_column (tb, COL_NAME)); | |
| scols_print_table (tb); | |
| scols_unref_table (tb); | |
| err: | |
| if (err) | |
| printf ("%s\n", err->message); | |
| pool_free (pool); | |
| return EXIT_SUCCESS; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment