summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pacman/download.c87
-rw-r--r--src/pacman/download.h3
-rw-r--r--src/pacman/log.c5
-rw-r--r--src/pacman/sync.c59
4 files changed, 112 insertions, 42 deletions
diff --git a/src/pacman/download.c b/src/pacman/download.c
index f994cab4..7727473b 100644
--- a/src/pacman/download.c
+++ b/src/pacman/download.c
@@ -31,6 +31,7 @@
#include <alpm.h>
/* pacman */
+#include "util.h"
#include "log.h"
#include "list.h"
#include "download.h"
@@ -126,8 +127,37 @@ static int copyfile(char *src, char *dest)
return(0);
}
+/*
+ * Download a list of files from a list of servers
+ * - if one server fails, we try the next one in the list
+ *
+ * RETURN: 0 for successful download, 1 on error
+ */
int downloadfiles(list_t *servers, const char *localpath, list_t *files)
{
+ return(!!downloadfiles_forreal(servers, localpath, files, NULL, NULL));
+}
+
+/*
+ * This is the real downloadfiles, used directly by sync_synctree() to check
+ * modtimes on remote (ftp only) files.
+ * - if *mtime1 is non-NULL, then only download files
+ * if they are different than *mtime1. String should be in the form
+ * "YYYYMMDDHHMMSS" to match the form of ftplib's FtpModDate() function.
+ * - if *mtime2 is non-NULL, then it will be filled with the mtime
+ * of the remote FTP file (from MDTM).
+ *
+ * NOTE: the *mtime option only works for FTP repositories, and won't work
+ * if XferCommand is used. We only use it to check mtimes on the
+ * repo db files.
+ *
+ * RETURN: 0 for successful download
+ * -1 if the mtimes are identical
+ * 1 on error
+ */
+int downloadfiles_forreal(list_t *servers, const char *localpath,
+ list_t *files, const char *mtime1, char *mtime2)
+{
int fsz;
netbuf *control = NULL;
list_t *lp;
@@ -145,7 +175,7 @@ int downloadfiles(list_t *servers, const char *localpath, list_t *files)
if(!pmo_xfercommand && strcmp(server->protocol, "file")) {
if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) {
FtpInit();
- vprint("Connecting to %s:21\n", server->server);
+ vprint("connecting to %s:21\n", server->server);
if(!FtpConnect(server->server, &control)) {
fprintf(stderr, "error: cannot connect to %s\n", server->server);
continue;
@@ -174,9 +204,9 @@ int downloadfiles(list_t *servers, const char *localpath, list_t *files)
host = (pmo_proxyhost) ? pmo_proxyhost : server->server;
port = (pmo_proxyhost) ? pmo_proxyport : 80;
if(strchr(host, ':')) {
- vprint("Connecting to %s\n", host);
+ vprint("connecting to %s\n", host);
} else {
- vprint("Connecting to %s:%u\n", host, port);
+ vprint("connecting to %s:%u\n", host, port);
}
if(!HttpConnect(host, port, &control)) {
fprintf(stderr, "error: cannot connect to %s\n", host);
@@ -296,21 +326,42 @@ int downloadfiles(list_t *servers, const char *localpath, list_t *files)
if(!FtpSize(fn, &fsz, FTPLIB_IMAGE, control)) {
fprintf(stderr, "warning: failed to get filesize for %s\n", fn);
}
- if(!stat(output, &st)) {
- offset = (int)st.st_size;
- if(!FtpRestart(offset, control)) {
- fprintf(stderr, "warning: failed to resume download -- restarting\n");
- /* can't resume: */
- /* unlink the file in order to restart download from scratch */
- unlink(output);
+ /* check mtimes */
+ if(mtime1 || mtime2) {
+ char fmtime[64];
+ if(!FtpModDate(fn, fmtime, sizeof(fmtime)-1, control)) {
+ fprintf(stderr, "warning: failed to get mtime for %s\n", fn);
+ } else {
+ strtrim(fmtime);
+ if(mtime1 && !strcmp(mtime1, fmtime)) {
+ /* mtimes are identical, skip this file */
+ vprint("mtimes are identical, skipping %s\n", fn);
+ filedone = -1;
+ complete = list_add(complete, fn);
+ }
+ if(mtime2) {
+ strncpy(mtime2, fmtime, 15); /* YYYYMMDDHHMMSS (=14b) */
+ mtime2[14] = '\0';
+ }
}
}
- if(!FtpGet(output, fn, FTPLIB_IMAGE, control)) {
- fprintf(stderr, "\nfailed downloading %s from %s: %s\n",
- fn, server->server, FtpLastResponse(control));
- /* we leave the partially downloaded file in place so it can be resumed later */
- } else {
- filedone = 1;
+ if(!filedone) {
+ if(!stat(output, &st)) {
+ offset = (int)st.st_size;
+ if(!FtpRestart(offset, control)) {
+ fprintf(stderr, "warning: failed to resume download -- restarting\n");
+ /* can't resume: */
+ /* unlink the file in order to restart download from scratch */
+ unlink(output);
+ }
+ }
+ if(!FtpGet(output, fn, FTPLIB_IMAGE, control)) {
+ fprintf(stderr, "\nfailed downloading %s from %s: %s\n",
+ fn, server->server, FtpLastResponse(control));
+ /* we leave the partially downloaded file in place so it can be resumed later */
+ } else {
+ filedone = 1;
+ }
}
} else if(!strcmp(server->protocol, "http") || (pmo_proxyhost && strcmp(server->protocol, "file"))) {
char src[PATH_MAX];
@@ -367,7 +418,7 @@ int downloadfiles(list_t *servers, const char *localpath, list_t *files)
}
}
- if(filedone) {
+ if(filedone > 0) {
char completefile[PATH_MAX];
if(!strcmp(server->protocol, "file")) {
char out[56];
@@ -385,6 +436,8 @@ int downloadfiles(list_t *servers, const char *localpath, list_t *files)
/* rename "output.part" file to "output" file */
snprintf(completefile, PATH_MAX, "%s/%s", localpath, fn);
rename(output, completefile);
+ } else if(filedone < 0) {
+ return(-1);
}
printf("\n");
fflush(stdout);
diff --git a/src/pacman/download.h b/src/pacman/download.h
index 22ecf574..a8278475 100644
--- a/src/pacman/download.h
+++ b/src/pacman/download.h
@@ -31,6 +31,9 @@ typedef struct __server_t {
} server_t;
int downloadfiles(list_t *servers, const char *localpath, list_t *files);
+int downloadfiles_forreal(list_t *servers, const char *localpath,
+ list_t *files, const char *mtime1, char *mtime2);
+
char *fetch_pkgurl(char *target);
#endif /* _PM_DOWNLOAD_H */
diff --git a/src/pacman/log.c b/src/pacman/log.c
index c0bb62b6..b5ab2400 100644
--- a/src/pacman/log.c
+++ b/src/pacman/log.c
@@ -107,7 +107,10 @@ void vprint(char *fmt, ...)
neednl = 0;
}
va_start(args, fmt);
- pm_fprintf(stdout, NL, fmt, args);
+ /* ORE
+ commented for now: it produces corruption
+ pm_fprintf(stdout, NL, fmt, args); */
+ vprintf(fmt, args);
va_end(args);
}
}
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index 86ede1cd..581d07e5 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -159,43 +159,54 @@ static int sync_cleancache(int level)
static int sync_synctree(list_t *syncs)
{
char *root, *dbpath;
+ char path[PATH_MAX];
list_t *i;
- int ret = 0;
+ int success = 0, ret;
alpm_get_option(PM_OPT_ROOT, (long *)&root);
alpm_get_option(PM_OPT_DBPATH, (long *)&dbpath);
for(i = syncs; i; i = i->next) {
- char path[PATH_MAX];
list_t *files = NULL;
+ char *mtime = NULL;
+ char newmtime[16] = "";
+ char lastupdate[16] = "";
sync_t *sync = (sync_t *)i->data;
+ /* get the lastupdate time */
+ snprintf(path, PATH_MAX, "%s/%s", path, sync->treename);
+ if(alpm_db_getlastupdate(sync->db, lastupdate) == -1) {
+ vprint("failed to get lastupdate time for %s (no big deal)\n", sync->treename);
+ }
+ mtime = lastupdate;
+
/* build a one-element list */
snprintf(path, PATH_MAX, "%s"PM_EXT_DB, sync->treename);
files = list_add(files, strdup(path));
snprintf(path, PATH_MAX, "%s%s", root, dbpath);
- if(downloadfiles(sync->servers, path, files)) {
- fprintf(stderr, "failed to synchronize %s\n", sync->treename);
- FREELIST(files);
- ret--;
- continue;
- }
-
+ ret = downloadfiles_forreal(sync->servers, path, files, mtime, newmtime);
+ vprint("sync: new mtime for %s: %s\n", sync->treename, newmtime);
FREELIST(files);
-
- snprintf(path, PATH_MAX, "%s%s/%s"PM_EXT_DB, root, dbpath, sync->treename);
- if(alpm_db_update(sync->treename, path) == -1) {
- fprintf(stderr, "error: %s\n", alpm_strerror(pm_errno));
- ret--;
+ if(ret > 0) {
+ fprintf(stderr, "failed to synchronize %s\n", sync->treename);
+ success--;
+ } else if(ret < 0) {
+ printf(":: %s is up to date\n", sync->treename);
+ } else {
+ snprintf(path, PATH_MAX, "%s%s/%s"PM_EXT_DB, root, dbpath, sync->treename);
+ if(alpm_db_update(sync->db, path, newmtime) == -1) {
+ fprintf(stderr, "error: failed to set database timestamp (%s)\n", alpm_strerror(pm_errno));
+ success--;
+ }
+ /* remove the .tar.gz */
+ unlink(path);
}
- /* remove the .tar.gz */
- unlink(path);
}
- return(ret);
+ return(success);
}
static int sync_search(list_t *syncs, list_t *targets)
@@ -375,13 +386,6 @@ int pacman_sync(list_t *targets)
return(sync_cleancache(pmo_s_clean));
}
- if(pmo_s_sync) {
- /* grab a fresh package list */
- MSG(NL, ":: Synchronizing package databases...\n");
- alpm_logaction("synchronizing package lists");
- sync_synctree(pmc_syncs);
- }
-
/* open the database(s) */
for(i = pmc_syncs; i; i = i->next) {
sync_t *sync = i->data;
@@ -391,6 +395,13 @@ int pacman_sync(list_t *targets)
}
}
+ if(pmo_s_sync) {
+ /* grab a fresh package list */
+ MSG(NL, ":: Synchronizing package databases...\n");
+ alpm_logaction("synchronizing package lists");
+ sync_synctree(pmc_syncs);
+ }
+
if(pmo_s_search) {
return(sync_search(pmc_syncs, targets));
}