commit 212ec919cdf4c3008e52169827eaeacb33af1aa0
Author: I-Fan, Chen <tick@openmoko.com>
Date:   Thu Dec 4 21:39:45 2008 +0800

    adding list_upgradable

diff --git a/libopkg/args.c b/libopkg/args.c
index d767bfb..1f681c7 100644
--- a/libopkg/args.c
+++ b/libopkg/args.c
@@ -267,6 +267,7 @@ void args_usage(char *complaint)
      printf("\nInformational Commands:\n");
      printf("\tlist    		List available packages and descriptions\n");
      printf("\tlist_installed		List all and only the installed packages and description \n");
+     printf("\tlist_upgradable		List all the installed and upgradable packages\n");
      printf("\tfiles <pkg>		List all files belonging to <pkg>\n");
      printf("\tsearch <file|regexp>		Search for a package providing <file>\n");
      printf("\tinfo [pkg|regexp]		Display all info for <pkg>\n");
diff --git a/libopkg/opkg.c b/libopkg/opkg.c
index 35ddb89..60475f3 100644
--- a/libopkg/opkg.c
+++ b/libopkg/opkg.c
@@ -929,47 +929,33 @@ opkg_list_packages (opkg_t *opkg, opkg_package_callback_t callback, void *user_d
 int
 opkg_list_upgradable_packages (opkg_t *opkg, opkg_package_callback_t callback, void *user_data)
 {
-  pkg_vec_t *all;
-  int i;
+    pkg_vec_t *all;
+    int i;
 
-  opkg_assert (opkg);
-  opkg_assert (callback);
+    opkg_assert (opkg);
+    opkg_assert (callback);
 
-  /* ensure all data is valid */
-  pkg_info_preinstall_check (opkg->conf);
+    /* ensure all data is valid */
+    pkg_info_preinstall_check (opkg->conf);
 
-  all = pkg_vec_alloc ();
-  pkg_hash_fetch_available (&opkg->conf->pkg_hash, all);
-  for (i = 0; i < all->len; i++)
-  {
-    pkg_t *old, *new;
-    int cmp;
-    opkg_package_t *package;
+    all = opkg_upgrade_all_list_get (opkg->conf);
+    for (i = 0; i < all->len; i++)
+    {
+        pkg_t *old, *new;
+        opkg_package_t *package;
 
-    old = all->pkgs[i];
-    
-    if (old->state_status != SS_INSTALLED)
-      continue;
+        old = all->pkgs[i];
 
-    new = pkg_hash_fetch_best_installation_candidate_by_name(opkg->conf, old->name, NULL);
-    if (new == NULL) {
-      /* XXX: Notice: Assuming locally install package is up to date */
-      continue;
-    }
-          
-    cmp = pkg_compare_versions(old, new);
+        new = pkg_hash_fetch_best_installation_candidate_by_name(opkg->conf, old->name, NULL);
 
-    if (cmp < 0)
-    {
-      package = old_pkg_to_new (new);
-      callback (opkg, package, user_data);
-      opkg_package_free (package);
+        package = old_pkg_to_new (new);
+        callback (opkg, package, user_data);
+        opkg_package_free (package);
     }
-  }
 
-  pkg_vec_free (all);
+    pkg_vec_free (all);
 
-  return 0;
+    return 0;
 }
 
 opkg_package_t*
diff --git a/libopkg/opkg_cmd.c b/libopkg/opkg_cmd.c
index 5b842bd..f5d78da 100644
--- a/libopkg/opkg_cmd.c
+++ b/libopkg/opkg_cmd.c
@@ -55,6 +55,7 @@ static int opkg_status_cmd(opkg_conf_t *conf, int argc, char **argv);
 static int opkg_install_pending_cmd(opkg_conf_t *conf, int argc, char **argv);
 static int opkg_install_cmd(opkg_conf_t *conf, int argc, char **argv);
 static int opkg_list_installed_cmd(opkg_conf_t *conf, int argc, char **argv);
+static int opkg_list_upgradable_cmd(opkg_conf_t *conf, int argc, char **argv);
 static int opkg_remove_cmd(opkg_conf_t *conf, int argc, char **argv);
 static int opkg_purge_cmd(opkg_conf_t *conf, int argc, char **argv);
 static int opkg_flag_cmd(opkg_conf_t *conf, int argc, char **argv);
@@ -81,6 +82,7 @@ static opkg_cmd_t cmds[] = {
      {"upgrade", 0, (opkg_cmd_fun_t)opkg_upgrade_cmd},
      {"list", 0, (opkg_cmd_fun_t)opkg_list_cmd},
      {"list_installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd},
+     {"list_upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd},
      {"info", 0, (opkg_cmd_fun_t)opkg_info_cmd},
      {"flag", 1, (opkg_cmd_fun_t)opkg_flag_cmd},
      {"status", 0, (opkg_cmd_fun_t)opkg_status_cmd},
@@ -782,6 +784,26 @@ static int opkg_list_installed_cmd(opkg_conf_t *conf, int argc, char **argv)
      return 0;
 }
 
+static int opkg_list_upgradable_cmd(opkg_conf_t *conf, int argc, char **argv) 
+{
+    pkg_vec_t *all = opkg_upgrade_all_list_get(conf);
+    pkg_t *_old_pkg, *_new_pkg;
+    char *old_v, *new_v;
+    int i;
+    for (i=0;i<all->len;i++) {
+        _old_pkg = all->pkgs[i];
+        _new_pkg = pkg_hash_fetch_best_installation_candidate_by_name(conf, _old_pkg->name, NULL);
+        old_v = pkg_version_str_alloc(_old_pkg);
+        new_v = pkg_version_str_alloc(_new_pkg);
+        if (opkg_cb_list)
+            opkg_cb_list(_old_pkg->name, new_v, old_v, _old_pkg->state_status, p_userdata);
+        free(old_v);
+        free(new_v);
+    }
+    pkg_vec_free(all);
+    return 0;
+}
+
 static int opkg_info_status_cmd(opkg_conf_t *conf, int argc, char **argv, int installed_only)
 {
      int i;
diff --git a/libopkg/opkg_upgrade.c b/libopkg/opkg_upgrade.c
index 925d9d8..d014979 100644
--- a/libopkg/opkg_upgrade.c
+++ b/libopkg/opkg_upgrade.c
@@ -77,3 +77,35 @@ int opkg_upgrade_pkg(opkg_conf_t *conf, pkg_t *old)
     new->state_flag |= SF_USER;
     return opkg_install_pkg(conf, new,1);
 }
+
+
+
+pkg_vec_t *opkg_upgrade_all_list_get(opkg_conf_t *conf) {
+    pkg_vec_t *all, *ans;
+    int i;
+
+    /* ensure all data is valid */
+    pkg_info_preinstall_check (conf);
+
+    all = pkg_vec_alloc ();
+    ans = pkg_vec_alloc ();
+    pkg_hash_fetch_all_installed (&conf->pkg_hash, all);
+    for (i = 0; i < all->len; i++)
+    {
+        pkg_t *old, *new;
+        int cmp;
+
+        old = all->pkgs[i];
+        new = pkg_hash_fetch_best_installation_candidate_by_name(conf, old->name, NULL);
+
+        if (new == NULL)
+            continue;
+
+        cmp = pkg_compare_versions(old, new);
+
+        if ( cmp < 0 )
+            pkg_vec_insert(ans, old);
+    }
+    pkg_vec_free (all);
+    return ans;
+}
diff --git a/libopkg/opkg_upgrade.h b/libopkg/opkg_upgrade.h
index d8e4b65..1523cee 100644
--- a/libopkg/opkg_upgrade.h
+++ b/libopkg/opkg_upgrade.h
@@ -14,3 +14,4 @@
 */
 
 int opkg_upgrade_pkg(opkg_conf_t *conf, pkg_t *old);
+pkg_vec_t *opkg_upgrade_all_list_get(opkg_conf_t *conf);
diff --git a/libopkg/pkg_vec.h b/libopkg/pkg_vec.h
index a316c50..0ec7489 100644
--- a/libopkg/pkg_vec.h
+++ b/libopkg/pkg_vec.h
@@ -42,7 +42,6 @@ pkg_vec_t * pkg_vec_alloc(void);
 void pkg_vec_free(pkg_vec_t *vec);
 void marry_two_packages(pkg_t * newpkg, pkg_t * oldpkg);
 
-void pkg_vec_add(pkg_vec_t *vec, pkg_t *pkg);
 /* pkg_vec_insert_merge: might munge pkg.
 *  returns the pkg that is in the pkg graph */
 pkg_t *pkg_vec_insert_merge(pkg_vec_t *vec, pkg_t *pkg, int set_status, opkg_conf_t *conf);
