00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00029 #include "config.h"
00030 #include <stdio.h>
00031 #include <unistd.h>
00032 #include <string.h>
00033 #include <locale.h>
00034 #include <glib.h>
00035 #include <glib/gi18n.h>
00036 #include <glib/gstdio.h>
00037 #include <apt-pkg/configuration.h>
00038 #include "langupdate.h"
00039 #include "aptcache.h"
00040 #define GNU_WARRANTY "Copyright (C) 2006-2009 Neil Williams <codehelp@debian.org>\n" \
00041 "This is free software; see the source for copying conditions. There is NO\n" \
00042 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
00043 #define DPKG_II "^Package: (.*)$"
00044 #define GREX_EMPTY GRegexMatchFlags(0)
00045 #define LOCALEGEN "/etc/locale.gen"
00046 #define STATUS_CHK "Status"
00047
00049 static guint c = 0;
00050 static const gchar * sourceslist = "/var/lib/"PACKAGE"/sources.list";
00051 static GList * installed = NULL;
00052 static GList * targets = NULL;
00053 static GHashTable * choices = NULL;
00073 static GList * not_ours = NULL;
00074 static GHashTable * orphans = NULL;
00075 static gchar * suite_codename = NULL;
00076 static gchar * user_suite = NULL;
00077 static gchar * mirror = NULL;
00078 static gint verbose = 0;
00079 static gboolean dry_run = false;
00080 static gboolean show_version = false;
00081 static gboolean purge_mode = false;
00082 static gchar * purge_names = NULL;
00083 static GOptionEntry entries[] =
00084 {
00085 { "dry-run", 'n', 0, G_OPTION_ARG_NONE, &dry_run,
00086 _("Only show the cache data, do not install"), 0 },
00087 { "mirror", 'm', 0, G_OPTION_ARG_STRING, &mirror,
00088 _("Use the specified TDeb mirror instead of the Emdebian default."),
00089 _("mirror_name")},
00090 { "autoremove", 'r', 0, G_OPTION_ARG_NONE, &purge_mode,
00091 _("Remove TDebs for unsupported locales."), 0},
00092 { "verbose", 'v', 0, G_OPTION_ARG_INT, &verbose, _("Specify verbose level [0-4]"),
00093 _("integer") },
00094 { "suite", 0, 0, G_OPTION_ARG_STRING, &user_suite,
00095 _("Specify the apt suite name [default unstable]"), _("codename") },
00096 { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, _("Show version information "
00097 "and exit."), 0},
00098 { NULL }
00099 };
00100
00113 #define APTARCHSTR " -o APT::Architecture="
00114
00122 #define APTCONFIGSTR "-o APT::Get::List-Cleanup=off " \
00123 "-o Apt::Install-Recommends=false " \
00124 "-o Dir=/var/lib/"PACKAGE" " \
00125 "-o Dir::Etc=/var/lib/"PACKAGE" " \
00126 "-o Dir::Etc::SourceList=sources.list " \
00127 "-o Dir::State::Status=/var/lib/"PACKAGE"/status "
00128
00129 gchar *
00130 lu_get_aptstring (void)
00131 {
00132 return g_strconcat (APTARCHSTR, HOST_CPU, " ", APTCONFIGSTR, "-o Dir::State=",
00133 suite_codename, " -o Dir::Cache=", suite_codename, NULL);
00134 }
00135
00140 static void
00141 output (gpointer key, gpointer data)
00142 {
00143 gchar * name, * hdl, * hdl_err, * config_str, * cmd, * func;
00144 gint err_status = 0;
00145 GError * gerr = NULL;
00146
00147 c++;
00148 g_print ("%s: %s %s\n", PACKAGE, _("installing:"), (gchar*)key);
00149 name = NULL;
00150 config_str = lu_get_aptstring();
00151 if (dry_run)
00152 {
00153 cmd = g_strdup("apt-cache");
00154 func = g_strdup("show");
00155 }
00156 else
00157 {
00158 cmd = g_strdup ("apt-get");
00159 func = g_strdup("install -y");
00160 }
00161 if ((key) && (strcmp ((gchar*)key, "")))
00162 name = g_strdup_printf ( "%s %s %s %s", cmd, config_str, func, (gchar*)key);
00163 g_free (config_str);
00164 if (verbose >= 4)
00165 g_print ("%s: %s %s\n", PACKAGE, _("running apt command: "), name);
00166 g_spawn_command_line_sync (name, &hdl, &hdl_err, &err_status, &gerr);
00167 g_free (name);
00168 g_free (cmd);
00169 g_free (func);
00170 if (gerr)
00171 {
00173 fprintf (stdout, _("apt returned an error:%s\n"), hdl_err);
00174 fprintf (stdout, _("status code:%d\n"), err_status);
00175 fprintf (stdout, "%s\n", gerr->message);
00176 fprintf (stdout, "%s\n", hdl);
00177 g_clear_error (&gerr);
00178 g_free (hdl_err);
00179 return;
00180 }
00181 if (dry_run)
00182 {
00183 fprintf (stdout, "%s\n", hdl);
00184 g_free (hdl);
00185 }
00186 }
00187
00197 static gchar *
00198 parse_installed (const gchar * pkg, const gchar * locale)
00199 {
00200 GList * match;
00201 gchar ** pos;
00202 gchar * r, *target, * lang, *src;
00203
00204 pos = g_strsplit (pkg, ": ", -1);
00205 if (!pos[0])
00206 return NULL;
00207 r = NULL;
00208 match = NULL;
00209 lang = g_strconcat ("-", LOCALE_SUFFIX, "-", locale, NULL);
00210 if (g_str_has_prefix(PACKAGE_CHK, pos[0]))
00211 {
00212 if (verbose >= 4)
00213 g_print ("Parsing %s\n", pos[1]);
00214 r = g_strdup (pos[1]);
00215 if (g_str_has_suffix (r, lang))
00216 {
00217 if (verbose >= 2)
00218 g_print ("Skipping %s\n", r);
00219 installed = g_list_prepend (installed, r);
00220
00221 targets = g_list_remove (targets, r);
00222 return NULL;
00223 }
00224 else
00225 {
00226 gchar * orphaned, * l;
00227
00228 orphaned = l = NULL;
00229 l = g_strconcat ("-", LOCALE_SUFFIX, "-", NULL);
00230 orphaned = g_strrstr_len (r, strlen(r), l);
00231 if (orphaned)
00232 g_hash_table_insert (orphans, g_strdup(r), g_strdup(""));
00233 orphaned = NULL;
00234 g_free (l);
00235 }
00236
00237 src = lu_get_sourcepkg (r);
00238 if (src)
00239 target = g_strconcat (src, lang, NULL);
00240 else
00241 target = g_strconcat (r, lang, NULL);
00242 match = g_list_find_custom (installed, target, check_pkg_name);
00243 if (g_list_length (match) != 0)
00244 targets = g_list_prepend (targets, target);
00245 g_strfreev (pos);
00246 g_free (r);
00247 return target;
00248 }
00249 g_free (lang);
00250 g_strfreev (pos);
00251 return NULL;
00252 }
00253
00255 static gboolean
00256 append_sourceslist (const gchar * lang)
00257 {
00258 FILE * fout = NULL;
00259
00260 fout = fopen (sourceslist, "a");
00261 if (!fout)
00262 {
00263 fout = fopen (sourceslist, "w+");
00264 }
00265 if (!fout)
00266 {
00267 g_warning (_("failed to create sources list: '%s'"), sourceslist);
00268 return false;
00269 }
00270 if ((mirror) && (!g_str_has_prefix(mirror, "http://www.emdebian.org/locale"))
00271 && (!g_str_has_prefix(mirror, "http://buildd.emdebian.org/locale")))
00272 {
00273 g_print ("%s: %s %s\n%s: %s %s\n", PACKAGE, _("Default Emdebian mirror:"),
00274 "http://www.emdebian.org/locale/", PACKAGE,
00275 _("Using specified mirror: "), mirror);
00276 fprintf (fout, "deb %s %s %s\n", mirror, suite_codename, lang);
00277 fprintf (fout, "deb-src %s %s %s\n", mirror, suite_codename, lang);
00278 if (verbose >= 3)
00279 {
00280 g_print ("%s: %s\n", PACKAGE, _("Adding temporary apt sources lines:"));
00281 g_print ("%s: %s %s %s %s\n", PACKAGE,
00282 "deb", mirror, suite_codename, lang);
00283 g_print ("%s: %s %s %s %s \n", PACKAGE,
00284 "deb-src", mirror, suite_codename, lang);
00285 }
00286 }
00287 else
00288 {
00289 if (verbose >= 2)
00290 {
00291 g_print ("%s: %s %s\n", PACKAGE, _("Using default Emdebian mirror:"),
00292 "http://www.emdebian.org/locale/");
00293 }
00294 fprintf (fout, "deb http://www.emdebian.org/locale/ %s %s\n",
00295 suite_codename, lang);
00296 fprintf (fout, "deb-src http://www.emdebian.org/locale/ %s %s\n",
00297 suite_codename, lang);
00298 if (verbose >= 3)
00299 {
00300 g_print ("%s: %s\n", PACKAGE, _("Adding temporary apt sources lines:"));
00301 g_print ("%s: %s %s %s\n", PACKAGE, "deb http://www.emdebian.org/locale/",
00302 suite_codename, lang);
00303 g_print ("%s: %s %s %s\n", PACKAGE, "deb-src http://www.emdebian.org/locale/",
00304 suite_codename, lang);
00305 }
00306 }
00307 fclose (fout);
00308 return true;
00309 }
00310
00319 static void
00320 lu_check_supported_suites(gchar * user_suite)
00321 {
00322 gchar * allowed, * match;
00323
00324
00325 if (mirror)
00326 return;
00327 match = NULL;
00328
00329
00330 g_print ("%s: %s %s\n", PACKAGE, _("checking Emdebian support for: "), user_suite);
00331 allowed = g_strdup("unstable sid testing lenny stable squeeze experimental");
00332 match = g_strrstr_len (allowed, strlen(allowed), user_suite);
00333 if (match)
00334 suite_codename = g_strdup(user_suite);
00335 else
00336 {
00337
00338 g_warning (_("Suite '%s' is not supported by Emdebian.\n"
00339 "Use the mirror option to specify a repository that can\n"
00340 "provide the '%s', suite"), user_suite, user_suite);
00341 g_print ("\n%s: %s", PACKAGE, _("Using the default Emdebian suite: unstable.\n"));
00342 suite_codename = g_strdup("unstable");
00343 }
00344 g_free (user_suite);
00345 g_free (allowed);
00346 }
00347
00348 static void
00349 remove_cache (const gchar * file, const gchar * user_suite)
00350 {
00351 gchar * path;
00352
00353 g_return_if_fail (file);
00354 g_return_if_fail (user_suite);
00355 path = g_strconcat ("/var/lib/", PACKAGE, "/", user_suite, "/", file, NULL);
00356 g_unlink (path);
00357 g_free (path);
00358 }
00359
00360 static void
00361 run_apt_clean (const gchar * user_suite)
00362 {
00363 gchar * config_str, * hdl, * hdl_err, * name;
00364 GError * gerr = NULL;
00365 gint err_status = 0;
00366
00367 g_return_if_fail (user_suite);
00368 config_str = lu_get_aptstring();
00369 name = g_strdup_printf ( "%s %s %s", "apt-get", config_str, "clean");
00370 g_spawn_command_line_sync (name, &hdl, &hdl_err, &err_status, &gerr);
00371 if (gerr)
00372 {
00374 g_printerr (_("apt returned an error:%s\n"), hdl_err);
00375 g_printerr (_("status code:%d\n"), err_status);
00376 g_printerr ("%s\n", gerr->message);
00377 g_clear_error (&gerr);
00378 g_free (hdl_err);
00379 return;
00380 }
00381 }
00382
00383 static void
00384 remove_lists (gchar * suite)
00385 {
00386 gchar * path, *file;
00387 const gchar * list;
00388 GDir * binlists;
00389
00390 g_return_if_fail (suite);
00391 path = g_strconcat ("/var/lib/",PACKAGE,"/", suite, "/lists/", NULL);
00392 binlists = g_dir_open (path, 0, NULL);
00393 if (binlists)
00394 {
00395 while ((list = g_dir_read_name (binlists)))
00396 {
00397 file = g_strconcat (path, list, NULL);
00398
00399 if (g_strcmp0(list, "partial"))
00400 g_unlink (file);
00401 g_free (file);
00402 }
00403 g_dir_close (binlists);
00404 }
00405 g_free (path);
00406 }
00407
00409 static gboolean
00410 lu_strip_components (gchar * line, gchar ** code, gchar ** root)
00411 {
00412 gchar * list;
00413 gchar ** tok;
00414 GError * gerr;
00415 GRegex * patt;
00416
00417 g_return_val_if_fail (line, FALSE);
00418 gerr = NULL;
00419 list = g_ascii_strdown (line, -1);
00420 tok = g_strsplit (list, ".", -1);
00421 g_free (list);
00422 list = g_strdup (tok[0]);
00423 g_strfreev (tok);
00424 tok = g_strsplit (list, " ", -1);
00425 g_free (list);
00426 list = g_strdup (tok[0]);
00427 g_strfreev (tok);
00428 patt = g_regex_new ("_", G_REGEX_OPTIMIZE, GREX_EMPTY, &gerr);
00429 if (gerr)
00430 {
00431 g_warning (gerr->message);
00432 g_clear_error (&gerr);
00433 return FALSE;
00434 }
00435 gerr = NULL;
00436 list = g_regex_replace (patt, list, -1, 0, "-", GREX_EMPTY, &gerr);
00437 if (gerr)
00438 {
00439 g_warning (gerr->message);
00440 g_clear_error (&gerr);
00441 return FALSE;
00442 }
00443 tok = g_strsplit (list, "-", -1);
00444 *root = g_strdup(tok[0]);
00445 g_strfreev (tok);
00446 *code = g_strdup (list);
00447 g_free (list);
00448 return TRUE;
00449 }
00450
00451 static void
00452 lu_purge_orphans (gpointer key, gpointer value, gpointer data)
00453 {
00454 gchar * names;
00455
00456 g_print ("DEBUG:oprhans_key=%s\n", (gchar*)key);
00457 names = g_strconcat (purge_names, " ", (gchar*)key, NULL);
00458 g_free (purge_names);
00459 purge_names = g_strdup(names);
00460 g_free (names);
00461 }
00462
00463 static gboolean
00464 lu_skip_not_ours (gpointer key, gpointer value, gpointer data)
00465 {
00466 gchar * match, * prefix;
00467
00468 match = g_strdup ((gchar*)data);
00469 match = g_strstrip (match);
00470 prefix = g_strconcat (match, "-", LOCALE_SUFFIX, "-", NULL);
00471 if (g_str_has_prefix((gchar*)key, prefix))
00472 {
00473 if (choices)
00474 {
00475 if (verbose >= 1)
00476 {
00477 g_print ("%s: %s '%s'\n", PACKAGE,
00478 _("Skipping Debian package"), (gchar*)data);
00479 }
00480 g_free (match);
00481 g_free (prefix);
00482 return TRUE;
00483 }
00484 }
00485 g_free (match);
00486 g_free (prefix);
00487 return FALSE;
00488 }
00489
00493 gint
00494 main (gint argc, gchar *argv[])
00495 {
00496 GError * em_gerr;
00497 gchar * dpkg, *code, *lgen, * log, * root, * name, *src;
00498 const gchar * const * locale_v;
00499 GList * dpkg_list, * p, *locales;
00500 GHashTable * tbl;
00501 gchar ** status_list, ** gen_list;
00502 guint mcount, c, l;
00503 gboolean pkg_changed;
00504 GOptionContext *context;
00505
00508 code = root = NULL;
00509 em_gerr = NULL;
00510 locales = dpkg_list = NULL;
00511 orphans = g_hash_table_new (g_str_hash, g_str_equal);
00512 tbl = g_hash_table_new (g_str_hash, g_str_equal);
00513 choices = g_hash_table_new (g_str_hash, g_str_equal);
00514 l = mcount = 0;
00515 #ifdef ENABLE_NLS
00516 setlocale (LC_ALL, "");
00517 bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
00518 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
00519 textdomain (GETTEXT_PACKAGE);
00520 #endif
00521 context = g_option_context_new (_("- updates language support for emdebian"));
00522 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
00523 g_option_context_set_summary (context,
00524 _("Apt frontend to match the Emdebian TDeb support with the installed\n"
00525 "packages and supported locales."));
00526 g_option_context_set_description (context,
00527
00528
00529
00530 _("Emdebian TDebs provide a method for splitting all translation files out of\n"
00531 "packages and into separate TDeb packages, organised by the locale root and\n"
00532 "source package. This allows individual users to only install translations\n"
00533 "files for the locales supported on their own machine and only for the\n"
00534 "packages installed at the time.\n\n"
00535 "Note that this functionality is not available for Debian TDebs.\n"));
00536 g_option_context_parse (context, &argc, &argv, &em_gerr);
00537 if (show_version)
00538 {
00539 g_print ("%s (%s)\n", PACKAGE, VERSION);
00540 g_print ("%s", GNU_WARRANTY);
00541 return (0);
00542 }
00543 if (!user_suite)
00544 suite_codename = g_strdup("unstable");
00545 else
00546 lu_check_supported_suites(user_suite);
00547 if (dry_run && !purge_mode)
00548 g_print ("%s: %s\n", PACKAGE,
00549 _("Dry run, just showing cache data for installable packages."));
00550 locale_v = g_get_language_names ();
00551 if (0 == strcmp (locale_v[l], "C"))
00552 return 0;
00553 while (strcmp (locale_v[l], "C") != 0)
00554 {
00555 gchar * line;
00556
00557 line = g_strdup (locale_v[l]);
00558 if (!lu_strip_components (line, &code, &root))
00559 continue;
00560 if (!code || !root)
00561 continue;
00562 g_free (line);
00563 locales = g_list_append (locales, code);
00564 if (!g_hash_table_lookup(tbl, root))
00565 {
00566 if (verbose >= 1)
00567 g_print ("%s: %s %s\n", PACKAGE,
00568 _("Environment needs support for:"), code);
00569 if (!append_sourceslist (root))
00570 return -1;
00571 if (verbose >= 1)
00572 g_print ("%s: %s %s\n", PACKAGE,
00573 _("Adding support for:"), root);
00574 g_hash_table_insert (tbl, root, code);
00575 }
00576 else
00577 {
00578 g_free (code);
00579 g_free (root);
00580 code = NULL;
00581 root = NULL;
00582 }
00583 l++;
00584 }
00585
00586 if (!g_file_get_contents (LOCALEGEN, &lgen, NULL, &em_gerr))
00587 {
00588 g_critical (em_gerr->message);
00589 g_message (_("Unable to open the locale.gen configuration file."));
00590 g_clear_error (&em_gerr);
00591 return -1;
00592 }
00593 gen_list = g_strsplit (lgen, "\n", -1);
00594 for (mcount = 0; mcount <= g_strv_length(gen_list); mcount++)
00595 {
00596 gchar * line;
00597
00598 if (!gen_list[mcount])
00599 continue;
00600 if (g_str_has_prefix (gen_list[mcount], "#"))
00601 continue;
00602 if (!g_strcmp0 ("", gen_list[mcount]))
00603 continue;
00604 line = g_strdup (gen_list[mcount]);
00605 if (!lu_strip_components (line, &code, &root))
00606 continue;
00607 if (!code || !root)
00608 continue;
00609 g_free (line);
00610 if (!g_hash_table_lookup(tbl, root))
00611 {
00612 locales = g_list_append (locales, root);
00613 if (verbose >= 1)
00614 g_print ("%s: %s %s\n", PACKAGE,
00615 _("/etc/locale.gen requires adding support for:"), code);
00616 if (!append_sourceslist (root))
00617 return -1;
00618 g_hash_table_insert (tbl, root, code);
00619 if (verbose >= 1)
00620 g_print ("%s: %s %s\n", PACKAGE,
00621 _("Adding support for:"), root);
00622 }
00623 g_free (code);
00624 }
00625 g_strfreev (gen_list);
00626
00627 g_return_val_if_fail (apt_init (sourceslist, suite_codename, verbose), -1);
00628 if (!g_file_get_contents (DPKG_FILE, &dpkg, NULL, &em_gerr))
00629 {
00630 g_critical (em_gerr->message);
00631 g_message (_("Unable to open the dpkg status file."));
00632 g_clear_error (&em_gerr);
00633 return -1;
00634 }
00635 status_list = g_strsplit (dpkg, "\n", -1);
00636 name = NULL;
00637 for (mcount = 0; mcount <= g_strv_length(status_list); mcount++)
00638 {
00639 gchar * pkg;
00640
00641 if (!status_list[mcount])
00642 continue;
00643 if (!g_strcmp0 (status_list[mcount], ""))
00644 {
00645 pkg_changed = TRUE;
00646 if (name)
00647 {
00648 g_free (name);
00649 name = NULL;
00650 }
00651 }
00652 else
00653 pkg_changed = FALSE;
00654 if (status_list[mcount+1] && g_str_has_prefix (status_list[mcount+1], STATUS_CHK))
00655 {
00656 gchar ** pos;
00657
00658 pos = g_strsplit (status_list[mcount], ": ", -1);
00659 if (g_str_has_suffix (status_list[mcount+1], "not-installed"))
00660 {
00661 g_strfreev (pos);
00662 continue;
00663 }
00664 g_strfreev (pos);
00665 }
00666 if ((!pkg_changed) && (g_str_has_prefix (status_list[mcount], "Version: ")))
00667 {
00668 gchar * em_chunk;
00669
00670
00671 em_chunk = g_strndup (status_list[mcount], strlen (status_list[mcount]) -1);
00672 if (!g_str_has_suffix (em_chunk, "em"))
00673 {
00674 gchar ** pkg_name;
00675
00676
00677
00678
00679 pkg_name = g_strsplit (name, ":", -1);
00680 if (g_strv_length(pkg_name) == 2)
00681 {
00682 gchar * chunk;
00683
00684 chunk = g_strdup (pkg_name[1]);
00685 chunk = g_strstrip (chunk);
00686 if (verbose >= 2)
00687 {
00688 g_print ("%s: %s: %s (%s)\n", PACKAGE,
00689 _("Not an Emdebian package"), chunk, status_list[mcount]);
00690 }
00691
00692 {
00693 src = lu_get_sourcepkg(chunk);
00694 if (src)
00695 not_ours = g_list_prepend (not_ours, g_strdup(src));
00696 }
00697 not_ours = g_list_prepend (not_ours, g_strdup(chunk));
00698 g_free (chunk);
00699 }
00700 g_strfreev (pkg_name);
00701 g_free (em_chunk);
00702 continue;
00703 }
00704 }
00705 if (g_str_has_prefix (status_list[mcount], PACKAGE_CHK))
00706 {
00707 if (!name)
00708 name = g_strdup (status_list[mcount]);
00709 name = g_strstrip (name);
00710 for (p = locales; p != NULL; p = p->next)
00711 {
00712 gchar * chunk;
00713
00714 chunk = g_strdup ((gchar*)p->data);
00715 chunk = g_strstrip (chunk);
00716
00717 src = lu_get_sourcepkg (chunk);
00718 if (src)
00719 pkg = parse_installed (status_list[mcount], src);
00720 else
00721 pkg = parse_installed (status_list[mcount], chunk);
00722 if (pkg)
00723 {
00724 dpkg_list = g_list_prepend (dpkg_list, pkg);
00725 }
00726 g_free (src);
00727 src = NULL;
00728 }
00729 }
00730 }
00731 g_strfreev (status_list);
00732 for (p = dpkg_list; p != NULL; p = p->next)
00733 {
00734 gboolean exists;
00735 gchar * pkg = g_strdup((gchar*)p->data);
00736 pkg = g_strstrip (pkg);
00737 src = lu_get_sourcepkg (pkg);
00738 if (src)
00739 exists= aptcache_lookup (src);
00740 else
00741 exists = aptcache_lookup (pkg);
00742 if (exists)
00743 {
00744 GList * done = NULL;
00745 done = g_list_find_custom (installed, pkg, check_pkg_name);
00746 if (done)
00747 {
00748 if ((verbose >= 1) && (!purge_mode))
00749 g_print ("%s: %s - %s\n", PACKAGE, pkg,
00750 _("TDeb is already installed."));
00751 continue;
00752 }
00753
00754
00755
00756 g_printerr ("DEBUG: adding %s\n", pkg);
00757 if (src)
00758 g_printerr ("DEBUG: from %s\n", src);
00759 g_hash_table_insert (choices, pkg, pkg);
00760 }
00761 }
00762 for (p = not_ours; p != NULL; p = p->next)
00763 {
00764 g_hash_table_foreach_remove (choices, lu_skip_not_ours, p->data);
00765 }
00766 c = g_hash_table_size (choices);
00767 if (!purge_mode)
00768 {
00769 GList * sorted = NULL;
00770
00771 if (c == 0)
00772 g_print ("%s: %s\n", PACKAGE, _("Nothing to do."));
00773 else
00774 {
00775 g_print ("%s: ", PACKAGE);
00776 g_print (ngettext("%d package to be installed\n",
00777 "%d packages to be installed\n", c), c);
00778 sorted = g_list_sort (g_hash_table_get_keys (choices), check_pkg_name);
00779 g_list_foreach (sorted, output, NULL);
00780 }
00781 }
00782 g_hash_table_destroy (tbl);
00783 g_hash_table_destroy (choices);
00784 run_apt_clean (suite_codename);
00785 remove_cache ("lists/lock", suite_codename);
00786 remove_cache ("lock", suite_codename);
00787 remove_cache ("srcpkgcache.bin", suite_codename);
00788 remove_cache ("pkgcache.bin", suite_codename);
00789 remove_lists (suite_codename);
00790 log = g_strconcat ("/var/lib/"PACKAGE"/var/log/apt/term.log", NULL);
00791 g_unlink (log);
00792 g_free (log);
00793 g_list_free (locales);
00794 g_unlink (sourceslist);
00795 if (purge_mode)
00796 {
00797 gchar * command;
00798
00799
00800
00801
00802 for (p = targets; p != NULL; p = p->next)
00803 {
00804 g_hash_table_remove (orphans, (gchar*)p->data);
00805 }
00806 for (p = installed; p != NULL; p = p->next)
00807 {
00808 g_hash_table_remove (orphans, (gchar*)p->data);
00809 }
00810 purge_names = g_strdup("");
00811 g_hash_table_foreach (orphans, lu_purge_orphans, NULL);
00812 if (g_strcmp0(purge_names, ""))
00813 {
00814 command = g_strconcat ("apt-get -y --purge remove ", purge_names, NULL);
00815 if (dry_run)
00816 g_print ("%s: %s '%s'\n", PACKAGE, _("Dry-run only."), command);
00817 else
00818 g_spawn_command_line_sync (command, NULL, NULL, NULL, &em_gerr);
00819 if (em_gerr)
00820 {
00821 g_critical (em_gerr->message);
00822 g_message (_("Unable to execute command: %s."), command);
00823 g_clear_error (&em_gerr);
00824 }
00825 g_free (command);
00826 }
00827 else
00828 g_print ("%s: %s\n", PACKAGE, _("No TDeb packages to remove."));
00829 }
00830 g_print ("\n");
00831 g_free (suite_codename);
00832 lu_clear_caches ();
00833 return 0;
00834 }
00835