From 72c24395762c985e404f65f7ec1064efed1d44b5 Mon Sep 17 00:00:00 2001 From: Aurelien Foret Date: Sun, 20 Mar 2005 09:22:03 +0000 Subject: Added support for .lastupdate files (from pacman 2.9.1) --- src/pacman/download.c | 87 +++++++++++++++++++++++++++++++++++++++++---------- src/pacman/download.h | 3 ++ src/pacman/log.c | 5 ++- src/pacman/sync.c | 59 ++++++++++++++++++++-------------- 4 files changed, 112 insertions(+), 42 deletions(-) (limited to 'src') 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 /* pacman */ +#include "util.h" #include "log.h" #include "list.h" #include "download.h" @@ -126,7 +127,36 @@ 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; @@ -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)); } -- cgit v1.2.3-24-g4f1b