summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJudd Vinet <judd@archlinux.org>2004-09-25 02:15:56 +0200
committerJudd Vinet <judd@archlinux.org>2004-09-25 02:15:56 +0200
commitdeff79c76c96ea1fd1f3e9eb682a9f9572a9e58e (patch)
treebd909537dc8500217f448bb92d91dde9681e1b58
parent4ffc53b3398ae845183f991a56207459256cc9e9 (diff)
downloadpacman-deff79c76c96ea1fd1f3e9eb682a9f9572a9e58e.tar.gz
pacman-deff79c76c96ea1fd1f3e9eb682a9f9572a9e58e.tar.xz
Imported from pacman-2.9.1.tar.gz
-rw-r--r--ChangeLog2
-rw-r--r--Makefile.in6
-rw-r--r--doc/pacman.8.in2
-rw-r--r--etc/current18
-rw-r--r--etc/extra18
-rw-r--r--etc/pacman.conf3
-rw-r--r--etc/release21
-rw-r--r--etc/unstable17
-rwxr-xr-xscripts/gensync2
-rwxr-xr-xscripts/makepkg2
-rwxr-xr-xscripts/makeworld2
-rwxr-xr-xscripts/updatesync2
-rw-r--r--src/db.c80
-rw-r--r--src/db.h2
-rw-r--r--src/pacman.c4
-rw-r--r--src/pacman.h2
-rw-r--r--src/pacsync.c165
-rw-r--r--src/pacsync.h5
18 files changed, 214 insertions, 139 deletions
diff --git a/ChangeLog b/ChangeLog
index ad237530..57990b58 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
VERSION DESCRIPTION
-----------------------------------------------------------------------------
+2.9.1 - --refresh now only downloads fresh packages lists if they've
+ been updated (currently only works with FTP)
2.9 - Improved -Rs functionality -- pacman now tracks why a package
is installed: explicitly, or as a dependency for another
package. -Rs will only remove dependencies that were not
diff --git a/Makefile.in b/Makefile.in
index 676f0742..b76705a8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -34,7 +34,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
-PACVER = 2.9
+PACVER = 2.9.1
TOPDIR = @srcdir@
SRCDIR = $(TOPDIR)/src/
@@ -108,10 +108,6 @@ install: pacman vercmp convertdb man
$(INSTALL) -D -m0644 $(MANSRC)makepkg.8 $(DESTDIR)$(MANDIR)/man8/makepkg.8
$(INSTALL) -D -m0644 etc/pacman.conf $(DESTDIR)/etc/pacman.conf
$(INSTALL) -D -m0644 etc/makepkg.conf $(DESTDIR)/etc/makepkg.conf
- $(INSTALL) -D -m0644 etc/current $(DESTDIR)/etc/pacman.d/current
- $(INSTALL) -D -m0644 etc/release $(DESTDIR)/etc/pacman.d/release
- $(INSTALL) -D -m0644 etc/extra $(DESTDIR)/etc/pacman.d/extra
- $(INSTALL) -D -m0644 etc/unstable $(DESTDIR)/etc/pacman.d/unstable
clean:
rm -f *~ $(OBJDIR)*.o $(MANSRC)*.8
diff --git a/doc/pacman.8.in b/doc/pacman.8.in
index 815cf6a6..52099522 100644
--- a/doc/pacman.8.in
+++ b/doc/pacman.8.in
@@ -219,7 +219,7 @@ global options.
.RS
.nf
[options]
-NoUpgrade = etc/passed etc/group etc/shadow
+NoUpgrade = etc/passwd etc/group etc/shadow
NoUpgrade = etc/fstab
Include = /etc/pacman.d/current
diff --git a/etc/current b/etc/current
deleted file mode 100644
index 81abdbd4..00000000
--- a/etc/current
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# CURRENT: Arch Linux core repository
-#
-[current]
-Server = ftp://ftp.archlinux.org/current/os/i686
-Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/current/os/i686
-Server = ftp://ftp.archlinux.de/pub/archlinux/current/os/i686
-Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/current/os/i686
-Server = http://archlinux.antesis.org/current/os/i686
-Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/current/os/i686
-Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/current/os/i686
-Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/current/os/i686
-Server = ftp://ftp.kegep.tuc.gr/archlinux/current/os/i686
-Server = http://darkstar.ist.utl.pt/archlinux/current/os/i686
-Server = ftp://archlinux.creativa.cl/current/os/i686
-Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/current/os/i686
-Server = ftp://saule.mintis.lt/pub/linux/current/os/i686
-Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/current/os/i686
diff --git a/etc/extra b/etc/extra
deleted file mode 100644
index d04af7c5..00000000
--- a/etc/extra
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# The Extra Repository
-#
-[extra]
-Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/extra/os/i686
-Server = ftp://ftp.archlinux.de/pub/archlinux/extra/os/i686
-Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/extra/os/i686
-Server = http://archlinux.antesis.org/extra/os/i686
-Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/extra/os/i686
-Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/extra/os/i686
-Server = ftp://ftp.archlinux.org/extra/os/i686
-Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/extra/os/i686
-Server = ftp://ftp.kegep.tuc.gr/archlinux/extra/os/i686
-Server = http://darkstar.ist.utl.pt/archlinux/extra/os/i686
-Server = ftp://archlinux.creativa.cl/extra/os/i686
-Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/extra/os/i686
-Server = ftp://saule.mintis.lt/pub/linux/extra/os/i686
-Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/extra/os/i686
diff --git a/etc/pacman.conf b/etc/pacman.conf
index 7711f440..42578338 100644
--- a/etc/pacman.conf
+++ b/etc/pacman.conf
@@ -33,6 +33,9 @@ HoldPkg = pacman glibc
# - local/custom mirrors can be added here or in separate files
#
+#[testing]
+#Server = ftp://ftp.archlinux.org/testing/os/i686
+
[current]
# Add your preferred servers here, they will be used first
Include = /etc/pacman.d/current
diff --git a/etc/release b/etc/release
deleted file mode 100644
index 7ede302d..00000000
--- a/etc/release
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# The Release tree. This tree is a snapshot view of the Current (core)
-# repository as it was when the last ISO was released.
-#
-# If you use the RELEASE tree, you should disable the CURRENT
-# tree to avoid conflicts
-#
-[release]
-Server = ftp://ftp.archlinux.org/release/os/i686
-Server = ftp://ftp.archlinux.de/pub/archlinux/release/os/i686
-Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/release/os/i686
-Server = http://archlinux.antesis.org/release/os/i686
-Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/release/os/i686
-Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/release/os/i686
-Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/release/os/i686
-Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/release/os/i686
-Server = ftp://ftp.kegep.tuc.gr/archlinux/release/os/i686
-Server = http://darkstar.ist.utl.pt/archlinux/release/os/i686
-Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/release/os/i686
-Server = ftp://saule.mintis.lt/pub/linux/release/os/i686
-Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/release/os/i686
diff --git a/etc/unstable b/etc/unstable
deleted file mode 100644
index 02ce7f5e..00000000
--- a/etc/unstable
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# The Unstable tree. Contains unstable or development versions of packages.
-#
-[unstable]
-Server = ftp://ftp.archlinux.org/unstable/os/i686
-Server = ftp://ftp.archlinux.de/pub/archlinux/unstable/os/i686
-Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/unstable/os/i686
-Server = http://archlinux.antesis.org/unstable/os/i686
-Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/unstable/os/i686
-Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/unstable/os/i686
-Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/unstable/os/i686
-Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/unstable/os/i686
-Server = http://darkstar.ist.utl.pt/archlinux/unstable/os/i686
-Server = ftp://archlinux.creativa.cl/unstable/os/i686
-Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/unstable/os/i686
-Server = ftp://saule.mintis.lt/pub/linux/unstable/os/i686
-Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/unstable/os/i686
diff --git a/scripts/gensync b/scripts/gensync
index 8dbe8921..f94a9bcb 100755
--- a/scripts/gensync
+++ b/scripts/gensync
@@ -20,7 +20,7 @@
# USA.
#
-myver='2.9'
+myver='2.9.1'
usage() {
echo "gensync $myver"
diff --git a/scripts/makepkg b/scripts/makepkg
index 98e2acc3..c0d217ff 100755
--- a/scripts/makepkg
+++ b/scripts/makepkg
@@ -20,7 +20,7 @@
# USA.
#
-myver='2.9'
+myver='2.9.1'
startdir=`pwd`
PKGDEST=$startdir
USE_COLOR="n"
diff --git a/scripts/makeworld b/scripts/makeworld
index 5346a0d5..3606a86b 100755
--- a/scripts/makeworld
+++ b/scripts/makeworld
@@ -21,7 +21,7 @@
#
toplevel=`pwd`
-version="2.9"
+version="2.9.1"
usage() {
echo "makeworld version $version"
diff --git a/scripts/updatesync b/scripts/updatesync
index 50dc26f0..6b851db5 100755
--- a/scripts/updatesync
+++ b/scripts/updatesync
@@ -21,7 +21,7 @@
# USA.
#
-myver='2.9'
+myver='2.9.1'
usage() {
echo "updatesync $myver"
diff --git a/src/db.c b/src/db.c
index 0faf5870..bc332466 100644
--- a/src/db.c
+++ b/src/db.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
+#include <sys/types.h>
#include <sys/stat.h>
#include <libgen.h>
#include <unistd.h>
@@ -43,7 +44,7 @@ pacdb_t* db_open(char *root, char *pkgdir, char *treename)
if(db->dir == NULL) {
return(NULL);
}
- strncpy(db->treename, treename, sizeof(db->treename));
+ strncpy(db->treename, treename, sizeof(db->treename)-1);
return(db);
}
@@ -61,6 +62,52 @@ void db_close(pacdb_t* db)
return;
}
+/* reads dbpath/.lastupdate and populates *ts with the contents.
+ * *ts should be malloc'ed and should be at least 15 bytes.
+ *
+ * Returns 0 on success, 1 on error
+ *
+ */
+int db_getlastupdate(const char *dbpath, char *ts)
+{
+ FILE *fp;
+ char path[PATH_MAX];
+ /* get the last update time, if it's there */
+ snprintf(path, PATH_MAX, "%s/.lastupdate", dbpath);
+ if((fp = fopen(path, "r")) == NULL) {
+ return(1);
+ } else {
+ char line[256];
+ if(fgets(line, sizeof(line), fp)) {
+ strncpy(ts, line, 15); /* YYYYMMDDHHMMSS */
+ ts[14] = '\0';
+ } else {
+ fclose(fp);
+ return(1);
+ }
+ }
+ fclose(fp);
+ return(0);
+}
+
+/* writes the db->path/.lastupdate with the contents of *ts
+ */
+int db_setlastupdate(const char *dbpath, const char *ts)
+{
+ FILE *fp;
+ char path[PATH_MAX];
+
+ snprintf(path, PATH_MAX, "%s/.lastupdate", dbpath);
+ if((fp = fopen(path, "w")) == NULL) {
+ return(1);
+ }
+ if(fputs(ts, fp) <= 0) {
+ fclose(fp);
+ return(1);
+ }
+ fclose(fp);
+ return(0);
+}
/* frees pkgcache if necessary and returns a new package
* cache from db
@@ -82,6 +129,8 @@ PMList* db_loadpkgs(pacdb_t *db)
pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
{
struct dirent *ent = NULL;
+ struct stat sbuf;
+ char path[PATH_MAX];
char name[256];
char *ptr = NULL;
int found = 0;
@@ -96,6 +145,11 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
continue;
}
strncpy(name, ent->d_name, 255);
+ /* stat the entry, make sure it's a directory */
+ snprintf(path, PATH_MAX, "%s/%s", db->path, name);
+ if(stat(path, &sbuf) || !S_ISDIR(sbuf.st_mode)) {
+ continue;
+ }
/* truncate the string at the second-to-last hyphen, */
/* which will give us the package name */
if((ptr = rindex(name, '-'))) {
@@ -115,15 +169,21 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
}
} else {
/* normal iteration */
- ent = readdir(db->dir);
- if(ent == NULL) {
- return(NULL);
- }
- if(!strcmp(ent->d_name, ".")) {
- ent = readdir(db->dir);
- }
- if(!strcmp(ent->d_name, "..")) {
+ int isdir = 0;
+ while(!isdir) {
ent = readdir(db->dir);
+ if(ent == NULL) {
+ return(NULL);
+ }
+ /* stat the entry, make sure it's a directory */
+ snprintf(path, PATH_MAX, "%s/%s", db->path, ent->d_name);
+ if(!stat(path, &sbuf) && S_ISDIR(sbuf.st_mode)) {
+ isdir = 1;
+ }
+ if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
+ isdir = 0;
+ continue;
+ }
}
}
return(db_read(db, ent, inforeq));
@@ -651,7 +711,7 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
}
if(!ok) {
MALLOC(str, 512);
- snprintf(str, 512, "%s: exists in filesystem", path);
+ snprintf(str, 512, "%s: %s: exists in filesystem", p->name, path);
conflicts = list_add(conflicts, str);
}
}
diff --git a/src/db.h b/src/db.h
index c070a323..eb346bdd 100644
--- a/src/db.h
+++ b/src/db.h
@@ -37,6 +37,8 @@ typedef struct __pacdb_t {
pacdb_t* db_open(char *root, char *dbpath, char *treename);
void db_close(pacdb_t *db);
+int db_getlastupdate(const char *dbpath, char *ts);
+int db_setlastupdate(const char *dbpath, const char *ts);
PMList* db_loadpkgs(pacdb_t *db);
pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq);
pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq);
diff --git a/src/pacman.c b/src/pacman.c
index 0e7e83c8..ef0995e4 100644
--- a/src/pacman.c
+++ b/src/pacman.c
@@ -1085,6 +1085,10 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
}
mb = (double)(totalsize / 1048576.0);
+ /* round up to 0.1 */
+ if(mb < 0.1) {
+ mb = 0.1;
+ }
printf("\nTargets: ");
str = buildstring(list);
indentprint(str, 9);
diff --git a/src/pacman.h b/src/pacman.h
index a87f569e..f6a76c7b 100644
--- a/src/pacman.h
+++ b/src/pacman.h
@@ -22,7 +22,7 @@
#define _PAC_PACMAN_H
#ifndef PACVER
-#define PACVER "2.9"
+#define PACVER "2.9.1"
#endif
#ifndef PKGDIR
diff --git a/src/pacsync.c b/src/pacsync.c
index 342f6c9c..bb1ad2ac 100644
--- a/src/pacsync.c
+++ b/src/pacsync.c
@@ -57,57 +57,111 @@ extern unsigned short pmo_nopassiveftp;
extern PMList *pmc_syncs;
extern int maxcols;
+/*
+ * Download fresh package lists for each repository
+ *
+ */
int sync_synctree()
{
- char ldir[PATH_MAX] = "";
char path[PATH_MAX];
+ char ldir[PATH_MAX] = "";
mode_t oldmask;
PMList *files = NULL;
PMList *i;
- int success = 0;
+ int success = 0, ret;
for(i = pmc_syncs; i; i = i->next) {
- sync_t *sync = (sync_t*)i->data;
+ char *mtime = NULL;
+ char newmtime[16] = "";
+ char lastupdate[16] = "";
+ sync_t *sync = (sync_t*)i->data;
snprintf(ldir, PATH_MAX, "%s%s", pmo_root, pmo_dbpath);
+ /* get the lastupdate time */
+ snprintf(path, PATH_MAX, "%s/%s", ldir, sync->treename);
+ if(db_getlastupdate(path, lastupdate)) {
+ vprint("failed to get lastupdate time for %s (no big deal)\n", sync->treename);
+ } else {
+ mtime = lastupdate;
+ }
+
/* build a one-element list */
snprintf(path, PATH_MAX, "%s.db.tar.gz", sync->treename);
files = list_add(files, strdup(path));
success = 1;
- if(downloadfiles(sync->servers, ldir, files)) {
+ ret = downloadfiles_forreal(sync->servers, ldir, files, mtime, newmtime);
+ vprint("pacsync: new mtime for %s: %s\n", sync->treename, newmtime);
+ FREELIST(files);
+ if(ret > 0) {
fprintf(stderr, "failed to synchronize %s\n", sync->treename);
success = 0;
- }
- FREELIST(files);
- snprintf(path, PATH_MAX, "%s/%s.db.tar.gz", ldir, sync->treename);
-
- if(success) {
- snprintf(ldir, PATH_MAX, "%s%s/%s", pmo_root, pmo_dbpath, sync->treename);
- /* remove the old dir */
- vprint("removing %s (if it exists)\n", ldir);
- rmrf(ldir);
-
- /* make the new dir */
- oldmask = umask(0000);
- mkdir(ldir, 0755);
- umask(oldmask);
-
- /* uncompress the sync database */
- vprint("Unpacking %s...\n", path);
- if(unpack(path, ldir, NULL)) {
- return(1);
+ } else if(ret < 0) {
+ printf(":: %s is up to date\n", sync->treename);
+ } else {
+ snprintf(path, PATH_MAX, "%s/%s.db.tar.gz", ldir, sync->treename);
+
+ if(success) {
+ snprintf(ldir, PATH_MAX, "%s%s/%s", pmo_root, pmo_dbpath, sync->treename);
+ /* remove the old dir */
+ vprint("removing %s (if it exists)\n", ldir);
+ rmrf(ldir);
+
+ /* make the new dir */
+ oldmask = umask(0000);
+ mkdir(ldir, 0755);
+ umask(oldmask);
+
+ /* uncompress the sync database */
+ vprint("unpacking %s...\n", path);
+ if(unpack(path, ldir, NULL)) {
+ return(1);
+ }
+
+ if(strlen(newmtime)) {
+ db_setlastupdate(ldir, newmtime);
+ }
}
+ /* remove the .tar.gz */
+ unlink(path);
}
- /* remove the .tar.gz */
- unlink(path);
}
return(!success);
}
+/*
+ * 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(PMList *servers, const char *localpath, PMList *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(PMList *servers, const char *localpath,
+ PMList *files, const char *mtime1, char *mtime2)
+{
int fsz;
netbuf *control = NULL;
PMList *lp;
@@ -125,7 +179,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *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;
@@ -153,9 +207,9 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *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);
@@ -275,21 +329,42 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *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 {
+ trim(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];
@@ -302,9 +377,9 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *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);
@@ -346,7 +421,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
}
}
- if(filedone) {
+ if(filedone > 0) {
char completefile[PATH_MAX];
if(!strcmp(server->protocol, "file")) {
char out[56];
@@ -364,6 +439,8 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *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/pacsync.h b/src/pacsync.h
index e4d97a12..14675355 100644
--- a/src/pacsync.h
+++ b/src/pacsync.h
@@ -31,6 +31,7 @@ typedef struct __server_t {
/* Repositories */
typedef struct __sync_t {
char* treename;
+ char* lastupdate;
PMList *servers;
} sync_t;
@@ -48,7 +49,11 @@ typedef struct __syncpkg_t {
} syncpkg_t;
int sync_synctree();
+
int downloadfiles(PMList *servers, const char *localpath, PMList *files);
+int downloadfiles_forreal(PMList *servers, const char *localpath,
+ PMList *files, const char *mtime1, char *mtime2);
+
syncpkg_t* find_pkginsync(char *needle, PMList *haystack);
PMList* rm_pkginsync(char *needle, PMList *haystack);