aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Woodward2004-07-15 15:23:39 +0000
committerJason Woodward2004-07-15 15:23:39 +0000
commit79e0228865f03dedc32d2c59d0cf2259bfb5d432 (patch)
tree31a390edc5abea966d8bb9361815e9de68e6819e
parente67e3049078f91779820e402c997a7dc9d61c576 (diff)
downloadslapt-get-79e0228865f03dedc32d2c59d0cf2259bfb5d432.tar.gz
support for only downloading package data if newer than cached during --update. now caches package data for each individual package sourch per --update run
-rw-r--r--ChangeLog3
-rw-r--r--po/en.po7
-rw-r--r--po/es.po7
-rw-r--r--po/es_ES.po7
-rw-r--r--po/it.po7
-rw-r--r--po/nl.po7
-rw-r--r--po/no.po7
-rw-r--r--po/pl.po7
-rw-r--r--po/pt_BR.po7
-rw-r--r--po/slapt-get.pot7
-rw-r--r--po/sv.po5
-rw-r--r--src/curl.c42
-rw-r--r--src/curl.h6
-rw-r--r--src/package.c153
-rw-r--r--src/package.h3
15 files changed, 229 insertions, 46 deletions
diff --git a/ChangeLog b/ChangeLog
index 4bdf29f..0efb3c7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
0.9.8g Jul 15, 2004
- * initial support for only downloading package data if newer than cached
+ * support for only downloading package data if newer than cached during --update
+ * now caches package data for each individual package sourch per --update run
* moved spinner and progress_callback from main.[ch] to curl.[ch]
* moved is_conflicted from action.[ch] to transaction.[ch]
* added swedish translation by Joel Bjurman (ypolt@lediga.st)
diff --git a/po/en.po b/po/en.po
index aa31f62..d459f87 100644
--- a/po/en.po
+++ b/po/en.po
@@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: 0.9.8e\n"
+"Project-Id-Version: 0.9.8g\n"
"POT-Creation-Date: 2003-11-03 14:28+0000\n"
-"PO-Revision-Date: 2004-05-28 15:00+0500\n"
+"PO-Revision-Date: 2004-07-15 10:00+0500\n"
"Last-Translator: Jason Woodward <woodwardj@jaos.org>\n"
"Language-Team: slapt-get-devel <slapt-get-devel@software.jaos.org>\n"
"MIME-Version: 1.0\n"
@@ -467,3 +467,6 @@ msgstr "skip dependency check"
msgid "show download statistics"
msgstr "show download statistics"
+msgid "Cached\n"
+msgstr "Cached\n"
+
diff --git a/po/es.po b/po/es.po
index 434300f..4c7742c 100644
--- a/po/es.po
+++ b/po/es.po
@@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: 0.9.8e\n"
+"Project-Id-Version: 0.9.8g\n"
"POT-Creation-Date: 2003-11-03 14:28+0000\n"
-"PO-Revision-Date: 2004-05-28 15:00+0500\n"
+"PO-Revision-Date: 2004-07-15 10:00+0500\n"
"Last-Translator: Ruben Gutierrez <ruben@snpp.com.ar>\n"
"Language-Team: slapt-get-devel <slapt-get-devel@software.jaos.org>\n"
"MIME-Version: 1.0\n"
@@ -467,3 +467,6 @@ msgstr "saltear chequeo de dependencias"
msgid "show download statistics"
msgstr "show download statistics"
+msgid "Cached\n"
+msgstr "Cached\n"
+
diff --git a/po/es_ES.po b/po/es_ES.po
index 536e009..bb3a82c 100644
--- a/po/es_ES.po
+++ b/po/es_ES.po
@@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: 0.9.8e\n"
+"Project-Id-Version: 0.9.8g\n"
"POT-Creation-Date: 2003-11-03 14:28+0000\n"
-"PO-Revision-Date: 2004-05-28 15:00+0500\n"
+"PO-Revision-Date: 2004-07-15 10:00+0500\n"
"Last-Translator: Ruben Gutierrez <ruben@snpp.com.ar>\n"
"Language-Team: slapt-get-devel <slapt-get-devel@software.jaos.org>\n"
"MIME-Version: 1.0\n"
@@ -467,3 +467,6 @@ msgstr "saltear la verificación de dependencias"
msgid "show download statistics"
msgstr "show download statistics"
+msgid "Cached\n"
+msgstr "Cached\n"
+
diff --git a/po/it.po b/po/it.po
index 8c58bdc..6d0f39e 100644
--- a/po/it.po
+++ b/po/it.po
@@ -6,9 +6,9 @@
#,fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: 0.9.8e\n"
+"Project-Id-Version: 0.9.8g\n"
"POT-Creation-Date: 2003-11-03 14:28+0000\n"
-"PO-Revision-Date: 2004-05-28 15:00+0500\n"
+"PO-Revision-Date: 2004-07-15 10:00+0500\n"
"Last-Translator: Francesco Gigli <jaramir@slack.it>\n"
"Language-Team: Italian <tp@lists.linux.it>\n"
"MIME-Version: 1.0\n"
@@ -467,3 +467,6 @@ msgstr "salta il controllo delle dipendenze"
msgid "show download statistics"
msgstr "show download statistics"
+msgid "Cached\n"
+msgstr "Cached\n"
+
diff --git a/po/nl.po b/po/nl.po
index 0f18a11..cae65b8 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: 0.9.8e\n"
+"Project-Id-Version: 0.9.8g\n"
"POT-Creation-Date: 2003-11-03 14:28+0000\n"
-"PO-Revision-Date: 2004-05-28 15:00+0500\n"
+"PO-Revision-Date: 2004-07-15 10:00+0500\n"
"Last-Translator: Jason Woodward <woodwardj@jaos.org>\n"
"Language-Team: slapt-get-devel <slapt-get-devel@software.jaos.org>\n"
"MIME-Version: 1.0\n"
@@ -467,3 +467,6 @@ msgstr "sla controle vereisten over"
msgid "show download statistics"
msgstr "show download statistics"
+msgid "Cached\n"
+msgstr "Cached\n"
+
diff --git a/po/no.po b/po/no.po
index 0917089..1608a02 100644
--- a/po/no.po
+++ b/po/no.po
@@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: 0.9.8e\n"
+"Project-Id-Version: 0.9.8g\n"
"POT-Creation-Date: 2003-11-03 14:28+0000\n"
-"PO-Revision-Date: 2004-05-28 15:00+0500\n"
+"PO-Revision-Date: 2004-07-15 10:00+0500\n"
"Last-Translator: Joran Kvalvaag <jk@nerdworks.org>\n"
"Language-Team: slapt-get-devel <slapt-get-devel@software.jaos.org>\n"
"MIME-Version: 1.0\n"
@@ -467,3 +467,6 @@ msgstr "ikke utfør avhengighetssjekk"
msgid "show download statistics"
msgstr "show download statistics"
+msgid "Cached\n"
+msgstr "Cached\n"
+
diff --git a/po/pl.po b/po/pl.po
index 81d6d81..bbd3142 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: 0.9.8e\n"
+"Project-Id-Version: 0.9.8g\n"
"POT-Creation-Date: 2003-11-03 14:28+0000\n"
-"PO-Revision-Date: 2004-05-28 15:00+0500\n"
+"PO-Revision-Date: 2004-07-15 10:00+0500\n"
"Last-Translators: Paul Blazejowski <paulb@blazebox.homeip.net>, nixon <nixon@klub.chip.pl> and simon <ssiimm@poczta.onet.pl>\n"
"Language-Team: slapt-get-devel <slapt-get-devel@software.jaos.org>\n"
"MIME-Version: 1.0\n"
@@ -467,3 +467,6 @@ msgstr "nie wykonuj sprawdzania zale¿no¶ci"
msgid "show download statistics"
msgstr "wyÅ^Ûwietl statystiki poboru"
+msgid "Cached\n"
+msgstr "Cached\n"
+
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 14b559b..3945fa1 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -5,9 +5,9 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: 0.9.8e\n"
+"Project-Id-Version: 0.9.8g\n"
"POT-Creation-Date: 2003-11-03 14:28+0000\n"
-"PO-Revision-Date: 2004-05-28 15:00+0500\n"
+"PO-Revision-Date: 2004-07-15 10:00+0500\n"
"Last-Translator: Henrique Pinto <henrique.pinto@kdemail.net>\n"
"Language-Team: slapt-get-devel <slapt-get-devel@software.jaos.org>\n"
"MIME-Version: 1.0\n"
@@ -466,3 +466,6 @@ msgstr "skip dependency check"
msgid "show download statistics"
msgstr "mostra estatísticas de download"
+msgid "Cached\n"
+msgstr "Cached\n"
+
diff --git a/po/slapt-get.pot b/po/slapt-get.pot
index 08f1b98..88b9afa 100644
--- a/po/slapt-get.pot
+++ b/po/slapt-get.pot
@@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: 0.9.8e\n"
+"Project-Id-Version: 0.9.8g\n"
"POT-Creation-Date: 2003-11-03 14:28+0000\n"
-"PO-Revision-Date: 2004-05-28 15:00+0500\n"
+"PO-Revision-Date: 2004-07-15 10:00+0500\n"
"Last-Translator: Jason Woodward <woodwardj@jaos.org>\n"
"Language-Team: slapt-get-devel <slapt-get-devel@software.jaos.org>\n"
"MIME-Version: 1.0\n"
@@ -467,3 +467,6 @@ msgstr ""
msgid "show download statistics"
msgstr ""
+msgid "Cached\n"
+msgstr ""
+
diff --git a/po/sv.po b/po/sv.po
index ff58435..7027fa8 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.9.8g\n"
"POT-Creation-Date: 2003-11-03 14:28+0000\n"
-"PO-Revision-Date: 2004-07-08 19:29+0500\n"
+"PO-Revision-Date: 2004-07-15 10:29+0500\n"
"Last-Translator: Joel Bjurman <ypolt@lediga.st>\n"
"Language-Team: slapt-get-devel <slapt-get-devel@software.jaos.org>\n"
"MIME-Version: 1.0\n"
@@ -467,3 +467,6 @@ msgstr "skippa beroendekoll"
msgid "show download statistics"
msgstr "visa nedladdningsstatistik"
+msgid "Cached\n"
+msgstr "Cached\n"
+
diff --git a/src/curl.c b/src/curl.c
index 473e7af..e1c8f58 100644
--- a/src/curl.c
+++ b/src/curl.c
@@ -17,6 +17,7 @@
*/
#include <main.h>
+static size_t write_header_callback(void *buffer, size_t size, size_t nmemb, void *userp);
int download_data(FILE *fh,const char *url,size_t bytes,int use_curl_dl_stats){
CURL *ch = NULL;
@@ -60,6 +61,47 @@ int download_data(FILE *fh,const char *url,size_t bytes,int use_curl_dl_stats){
return return_code;
}
+static size_t write_header_callback(void *buffer, size_t size, size_t nmemb, void *userp){
+ char *tmp;
+ register int a_size = size * nmemb;
+ struct head_data_t *head_t = (struct head_data_t *)userp;
+
+ tmp = (char *)realloc( head_t->data, head_t->size + a_size + 1);
+ if( tmp != NULL ){
+ head_t->data = tmp;
+ /* strncat(head_t->data,buffer,a_size); */
+ memcpy(&(head_t->data[head_t->size]),buffer,a_size);
+ head_t->size += a_size;
+ }
+
+ return nmemb;
+}
+
+char *head_request(const char *url){
+ CURL *ch = NULL;
+ CURLcode response;
+ struct head_data_t head_t;
+
+ head_t.data = NULL;
+ head_t.size = 0;
+
+ ch = curl_easy_init();
+ curl_easy_setopt(ch, CURLOPT_URL, url);
+ curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, write_header_callback);
+ curl_easy_setopt(ch, CURLOPT_FILE, &head_t);
+ curl_easy_setopt(ch, CURLOPT_HEADER, 1);
+ curl_easy_setopt(ch, CURLOPT_NOBODY, 1);
+
+ if( (response = curl_easy_perform(ch)) != 0 ){
+ free(head_t.data);
+ curl_easy_cleanup(ch);
+ return NULL;
+ }
+
+ return head_t.data;
+
+}
+
int get_mirror_data_from_source(FILE *fh,int use_curl_dl_stats,const char *base_url,const char *filename){
int return_code = 0;
char *url = NULL;
diff --git a/src/curl.h b/src/curl.h
index 14fb422..297225e 100644
--- a/src/curl.h
+++ b/src/curl.h
@@ -16,8 +16,14 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+struct head_data_t {
+ char *data;
+ size_t size;
+};
+
/* this is the main download routine */
int download_data(FILE *fh,const char *url,size_t bytes,int use_curl_dl_stats);
+char *head_request(const char *url);
/*
this fills FILE with data from url, used for PACKAGES.TXT and CHECKSUMS
diff --git a/src/package.c b/src/package.c
index 7e3e48d..d51892a 100644
--- a/src/package.c
+++ b/src/package.c
@@ -1393,6 +1393,76 @@ pkg_info_t *get_pkg_by_details(struct pkg_list *list,char *name,char *version,ch
return NULL;
}
+/* do a head request on the mirror data to find out if it's new */
+int head_mirror_data(const char *wurl,const char *file){
+ int return_code = -1;
+ char *last_modified,*last_modified_ptr,*newline_ptr,*head_data;
+ int last_modified_len;
+ char *url;
+ char *head_filename,*filename;
+ FILE *tmp;
+ char *getline_buffer = NULL;
+ size_t gl_n;
+ ssize_t gl_return_size;
+
+ /* build url */
+ url = calloc( strlen(wurl) + strlen(file) + 2, sizeof *url );
+ strncat(url,wurl,strlen(wurl));
+ strncat(url,"/",1);
+ strncat(url,file,strlen(file));
+
+ /* retrieve the header info */
+ head_data = head_request(url);
+ if( head_data == NULL ){
+ free(head_data);
+ free(url);
+ return -1;
+ }
+ /* extract the last modified date for storage and later comparison */
+ last_modified_ptr = strstr(head_data,"Last-Modified");
+ newline_ptr = strpbrk(last_modified_ptr,"\r\n");
+ if( last_modified_ptr == NULL || newline_ptr == NULL ){
+ free(head_data);
+ free(url);
+ return -1;
+ }
+ last_modified_len = strlen(last_modified_ptr) - strlen(newline_ptr);
+ last_modified = calloc( last_modified_len + 1, sizeof *last_modified );
+ memcpy(last_modified,last_modified_ptr,last_modified_len);
+
+ /* store the header last modified date for later use */
+ filename = gen_filename_from_url(wurl,file);
+ head_filename = calloc( strlen(filename) + strlen(HEAD_FILE_EXT) + 1, sizeof *head_filename );
+ strncat(head_filename,filename,strlen(filename));
+ strncat(head_filename,HEAD_FILE_EXT,strlen(HEAD_FILE_EXT));
+
+ tmp = open_file(head_filename,"a+");
+ if( tmp == NULL ) exit(1);
+ rewind(tmp);
+ gl_return_size = getline(&getline_buffer, &gl_n, tmp);
+ if( gl_return_size == -1 ){
+ /* we must not have had an existing last modified date */
+ return_code = -1;
+ }else{
+ /* if retrieved modified date and current are the same */
+ if( strcmp(last_modified,getline_buffer) == 0 ) return_code = 0;
+ }
+ fclose(tmp);
+
+ /* store the last modified date */
+ tmp = open_file(head_filename,"w");
+ if( tmp == NULL ) exit(1);
+ fprintf(tmp,"%s",last_modified);
+ fclose(tmp);
+
+ free(filename);
+ free(head_filename);
+ free(last_modified);
+ free(url);
+ free(head_data);
+ return return_code;
+}
+
/* update package data from mirror url */
void update_pkg_cache(const rc_config *global_config){
int i,source_dl_failed = 0;
@@ -1408,59 +1478,90 @@ void update_pkg_cache(const rc_config *global_config){
struct pkg_list *patch_pkgs = NULL;
char *pkg_filename,*patch_filename,*checksum_filename;
+
/* download our PKG_LIST */
- pkg_filename = gen_filename_from_url(global_config->sources.url[i],PKG_LIST);
- tmp_pkg_f = fopen(pkg_filename,"w+b");
- free(pkg_filename);
if( global_config->dl_stats == 1 ){
printf(_("Retrieving package data [%s]...\n"),global_config->sources.url[i]);
}else{
printf(_("Retrieving package data [%s]..."),global_config->sources.url[i]);
}
- if( get_mirror_data_from_source(tmp_pkg_f,global_config->dl_stats,global_config->sources.url[i],PKG_LIST) == 0 ){
- rewind(tmp_pkg_f); /* make sure we are back at the front of the file */
+ pkg_filename = gen_filename_from_url(global_config->sources.url[i],PKG_LIST);
+
+ /* open for reading if cached, otherwise write it from the downloaded data */
+ if( head_mirror_data(global_config->sources.url[i],PKG_LIST) == 0 ){
+ if( global_config->dl_stats != 1 ) printf(_("Cached\n"));
+ tmp_pkg_f = fopen(pkg_filename,"r");
available_pkgs = parse_packages_txt(tmp_pkg_f);
- if( global_config->dl_stats != 1 ) printf(_("Done\n"));
}else{
- source_dl_failed = 1;
+ tmp_pkg_f = fopen(pkg_filename,"w+b");
+ if( get_mirror_data_from_source(tmp_pkg_f,global_config->dl_stats,global_config->sources.url[i],PKG_LIST) == 0 ){
+ rewind(tmp_pkg_f); /* make sure we are back at the front of the file */
+ available_pkgs = parse_packages_txt(tmp_pkg_f);
+ if( global_config->dl_stats != 1 ) printf(_("Done\n"));
+ }else{
+ source_dl_failed = 1;
+ }
}
+ free(pkg_filename);
fclose(tmp_pkg_f);
+
/* download PATCHES_LIST */
- patch_filename = gen_filename_from_url(global_config->sources.url[i],PATCHES_LIST);
- tmp_patch_f = fopen(patch_filename,"w+b");
- free(patch_filename);
if( global_config->dl_stats == 1 ){
printf(_("Retrieving patch list [%s]...\n"),global_config->sources.url[i]);
}else{
printf(_("Retrieving patch list [%s]..."),global_config->sources.url[i]);
}
- if( get_mirror_data_from_source(tmp_patch_f,global_config->dl_stats,global_config->sources.url[i],PATCHES_LIST) == 0 ){
- rewind(tmp_patch_f); /* make sure we are back at the front of the file */
+ patch_filename = gen_filename_from_url(global_config->sources.url[i],PATCHES_LIST);
+
+ /* open for reading if cached, otherwise write it from the downloaded data */
+ if( head_mirror_data(global_config->sources.url[i],PATCHES_LIST) == 0 ){
+ if( global_config->dl_stats != 1 ) printf(_("Cached\n"));
+ tmp_patch_f = fopen(patch_filename,"r");
patch_pkgs = parse_packages_txt(tmp_patch_f);
- if( global_config->dl_stats != 1 ) printf(_("Done\n"));
}else{
- /* we don't care if the patch fails, for example current doesn't have patches */
- /* source_dl_failed = 1; */
+ tmp_patch_f = fopen(patch_filename,"w+b");
+ if( get_mirror_data_from_source(tmp_patch_f,global_config->dl_stats,global_config->sources.url[i],PATCHES_LIST) == 0 ){
+ rewind(tmp_patch_f); /* make sure we are back at the front of the file */
+ patch_pkgs = parse_packages_txt(tmp_patch_f);
+ if( global_config->dl_stats != 1 ) printf(_("Done\n"));
+ }else{
+ /* we don't care if the patch fails, for example current doesn't have patches */
+ /* source_dl_failed = 1; */
+ }
}
+ free(patch_filename);
fclose(tmp_patch_f);
+
/* download checksum file */
- checksum_filename = gen_filename_from_url(global_config->sources.url[i],CHECKSUM_FILE);
- tmp_checksum_f = fopen(checksum_filename,"w+b");
- free(checksum_filename);
if( global_config->dl_stats == 1 ){
- printf(_("Retrieving checksum list [%s]...\n"),global_config->sources.url[i]);
+ printf(_("Retrieving checksum list [%s]...\n"), global_config->sources.url[i]);
}else{
- printf(_("Retrieving checksum list [%s]..."),global_config->sources.url[i]);
+ printf(_("Retrieving checksum list [%s]..."), global_config->sources.url[i]);
}
- if( get_mirror_data_from_source(tmp_checksum_f,global_config->dl_stats,global_config->sources.url[i],CHECKSUM_FILE) == 0 ){
- int a;
+ checksum_filename = gen_filename_from_url(global_config->sources.url[i],CHECKSUM_FILE);
+
+ /* open for reading if cached, otherwise write it from the downloaded data */
+ if( head_mirror_data(global_config->sources.url[i],CHECKSUM_FILE) == 0 ){
+ if( global_config->dl_stats != 1 ) printf(_("Cached\n"));
+ tmp_checksum_f = fopen(checksum_filename,"r");
+ }else{
+ tmp_checksum_f = fopen(checksum_filename,"w+b");
+ if( get_mirror_data_from_source(
+ tmp_checksum_f,global_config->dl_stats,global_config->sources.url[i],CHECKSUM_FILE
+ ) != 0
+ ) source_dl_failed = 1;
if( global_config->dl_stats != 1 ) printf(_("Done\n"));
+ rewind(tmp_checksum_f); /* make sure we are back at the front of the file */
+ }
+
+ /* if the download failed don't do this, do it if cached or d/l was good */
+ if( source_dl_failed != 1 ){
+ int a;
/* now map md5 checksums to packages */
printf(_("Reading Package Lists..."));
- rewind(tmp_checksum_f); /* make sure we are back at the front of the file */
if( available_pkgs != NULL ){
for(a = 0;a < available_pkgs->pkg_count;a++){
get_md5sum(available_pkgs->pkgs[a],tmp_checksum_f);
@@ -1474,9 +1575,9 @@ void update_pkg_cache(const rc_config *global_config){
}
}
printf(_("Done\n"));
- }else{
- source_dl_failed = 1;
+
}
+ free(checksum_filename);
fclose(tmp_checksum_f);
/* write package listings to disk */
@@ -1489,7 +1590,7 @@ void update_pkg_cache(const rc_config *global_config){
free_pkg_list(patch_pkgs);
}
- }
+ }/* end for loop */
/* if all our downloads where a success, write to PKG_LIST_L */
if( source_dl_failed != 1 ){
diff --git a/src/package.h b/src/package.h
index 8706b82..4ad4bd5 100644
--- a/src/package.h
+++ b/src/package.h
@@ -49,6 +49,7 @@
#define INSTALL_CMD "/sbin/installpkg "
#define UPGRADE_CMD "/sbin/upgradepkg --reinstall "
#define CHECKSUM_FILE "CHECKSUMS.md5"
+#define HEAD_FILE_EXT ".head"
struct _pkg_info {
char name[NAME_LEN];
@@ -90,6 +91,8 @@ void add_pkg_to_pkg_list(struct pkg_list *list,pkg_info_t *pkg);
/* free memory allocated for pkg_list struct */
void free_pkg_list(struct pkg_list *);
+/* do a head request on the mirror data to find out if it's new */
+int head_mirror_data(const char *wurl,const char *file);
/* update the local package cache */
void update_pkg_cache(const rc_config *global_config);
/* parse the PACKAGES.TXT file */