summaryrefslogtreecommitdiffstats
path: root/src/pacsync.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pacsync.c')
-rw-r--r--src/pacsync.c372
1 files changed, 210 insertions, 162 deletions
diff --git a/src/pacsync.c b/src/pacsync.c
index 54366cca..0c41f543 100644
--- a/src/pacsync.c
+++ b/src/pacsync.c
@@ -48,6 +48,7 @@ static struct timeval t0, t;
extern char *pmo_root;
extern char *pmo_dbpath;
extern char *pmo_proxyhost;
+extern char *pmo_xfercommand;
extern unsigned short pmo_proxyport;
extern unsigned short pmo_nopassiveftp;
@@ -105,7 +106,7 @@ int sync_synctree()
return(!success);
}
-int downloadfiles(PMList *servers, char *localpath, PMList *files)
+int downloadfiles(PMList *servers, const char *localpath, PMList *files)
{
int fsz;
netbuf *control = NULL;
@@ -121,197 +122,244 @@ int downloadfiles(PMList *servers, char *localpath, PMList *files)
for(i = servers; i && !done; i = i->next) {
server_t *server = (server_t*)i->data;
- if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) {
- FtpInit();
- vprint("Connecting to %s:21\n", server->server);
- if(!FtpConnect(server->server, &control)) {
- fprintf(stderr, "error: cannot connect to %s\n", server->server);
- continue;
- }
- if(!FtpLogin("anonymous", "arch@guest", control)) {
- fprintf(stderr, "error: anonymous login failed\n");
- FtpQuit(control);
- continue;
- }
- if(!FtpChdir(server->path, control)) {
- fprintf(stderr, "error: could not cwd to %s: %s\n", server->path,
- FtpLastResponse(control));
- continue;
- }
- if(!pmo_nopassiveftp) {
- if(!FtpOptions(FTPLIB_CONNMODE, FTPLIB_PASSIVE, control)) {
- fprintf(stderr, "warning: failed to set passive mode\n");
+ if(!pmo_xfercommand) {
+ if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) {
+ FtpInit();
+ vprint("Connecting to %s:21\n", server->server);
+ if(!FtpConnect(server->server, &control)) {
+ fprintf(stderr, "error: cannot connect to %s\n", server->server);
+ continue;
+ }
+ if(!FtpLogin("anonymous", "arch@guest", control)) {
+ fprintf(stderr, "error: anonymous login failed\n");
+ FtpQuit(control);
+ continue;
+ }
+ if(!FtpChdir(server->path, control)) {
+ fprintf(stderr, "error: could not cwd to %s: %s\n", server->path,
+ FtpLastResponse(control));
+ continue;
+ }
+ if(!pmo_nopassiveftp) {
+ if(!FtpOptions(FTPLIB_CONNMODE, FTPLIB_PASSIVE, control)) {
+ fprintf(stderr, "warning: failed to set passive mode\n");
+ }
+ } else {
+ vprint("FTP passive mode not set\n");
+ }
+ } else if(pmo_proxyhost) {
+ char *host;
+ unsigned port;
+ host = (pmo_proxyhost) ? pmo_proxyhost : server->server;
+ port = (pmo_proxyhost) ? pmo_proxyport : 80;
+ if(strchr(host, ':')) {
+ vprint("Connecting to %s\n", host);
+ } else {
+ vprint("Connecting to %s:%u\n", host, port);
+ }
+ if(!HttpConnect(host, port, &control)) {
+ fprintf(stderr, "error: cannot connect to %s\n", host);
+ continue;
}
- } else {
- vprint("FTP passive mode not set\n");
- }
- } else if(pmo_proxyhost) {
- char *host;
- unsigned port;
- host = (pmo_proxyhost) ? pmo_proxyhost : server->server;
- port = (pmo_proxyhost) ? pmo_proxyport : 80;
- if(strchr(host, ':')) {
- vprint("Connecting to %s\n", host);
- } else {
- vprint("Connecting to %s:%u\n", host, port);
- }
- if(!HttpConnect(host, port, &control)) {
- fprintf(stderr, "error: cannot connect to %s\n", host);
- continue;
}
- }
- /* set up our progress bar's callback (and idle timeout) */
- if(strcmp(server->protocol, "file") && control) {
- FtpOptions(FTPLIB_CALLBACK, (long)log_progress, control);
- FtpOptions(FTPLIB_IDLETIME, (long)1000, control);
- FtpOptions(FTPLIB_CALLBACKARG, (long)&fsz, control);
- FtpOptions(FTPLIB_CALLBACKBYTES, (10*1024), control);
+ /* set up our progress bar's callback (and idle timeout) */
+ if(strcmp(server->protocol, "file") && control) {
+ FtpOptions(FTPLIB_CALLBACK, (long)log_progress, control);
+ FtpOptions(FTPLIB_IDLETIME, (long)1000, control);
+ FtpOptions(FTPLIB_CALLBACKARG, (long)&fsz, control);
+ FtpOptions(FTPLIB_CALLBACKBYTES, (10*1024), control);
+ }
}
/* get each file in the list */
for(lp = files; lp; lp = lp->next) {
- char output[PATH_MAX];
- int j, filedone = 0;
char *fn = (char*)lp->data;
- char *ptr;
- struct stat st;
if(is_in(fn, complete)) {
continue;
}
- snprintf(output, PATH_MAX, "%s/%s.part", localpath, fn);
- strncpy(sync_fnm, fn, 24);
- /* drop filename extension */
- ptr = strstr(fn, ".db.tar.gz");
- if(ptr && (ptr-fn) < 24) {
- sync_fnm[ptr-fn] = '\0';
- }
- ptr = strstr(fn, ".pkg.tar.gz");
- if(ptr && (ptr-fn) < 24) {
- sync_fnm[ptr-fn] = '\0';
- }
- for(j = strlen(sync_fnm); j < 24; j++) {
- sync_fnm[j] = ' ';
- }
- sync_fnm[24] = '\0';
- offset = 0;
-
- /* ETA setup */
- gettimeofday(&t0, NULL);
- t = t0;
- rate = 0;
- xfered1 = 0;
- eta_h = 0;
- eta_m = 0;
- eta_s = 0;
-
- if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) {
- if(!FtpSize(fn, &fsz, FTPLIB_IMAGE, control)) {
- fprintf(stderr, "warning: failed to get filesize for %s\n", fn);
+ if(pmo_xfercommand) {
+ int ret;
+ char *ptr1, *ptr2;
+ char origCmd[PATH_MAX];
+ char parsedCmd[PATH_MAX] = "";
+ char url[PATH_MAX];
+ char cwd[PATH_MAX];
+ /* build the full download url */
+ snprintf(url, PATH_MAX, "%s://%s%s%s", server->protocol, server->server,
+ server->path, fn);
+ /* replace all occurrences of %u with the download URL */
+ strncpy(origCmd, pmo_xfercommand, sizeof(origCmd));
+ ptr1 = origCmd;
+ while((ptr2 = strstr(ptr1, "%u"))) {
+ ptr2[0] = '\0';
+ strcat(parsedCmd, ptr1);
+ strcat(parsedCmd, url);
+ ptr1 = ptr2 + 2;
}
- 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);
- }
+ strcat(parsedCmd, ptr1);
+ /* cwd to the download directory */
+ getcwd(cwd, PATH_MAX);
+ if(chdir(localpath)) {
+ fprintf(stderr, "error: could not chdir to %s\n", localpath);
+ return(1);
}
- 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 */
+ /* execute the parsed command via /bin/sh -c */
+ vprint("running command: %s\n", parsedCmd);
+ ret = system(parsedCmd);
+ if(ret == -1) {
+ fprintf(stderr, "error running XferCommand: fork failed!\n");
+ return(1);
+ } else if(ret != 0) {
+ /* download failed */
+ vprint("XferCommand command returned non-zero status code (%d)\n",
+ WEXITSTATUS(ret));
} else {
- filedone = 1;
+ /* download was successful */
+ complete = list_add(complete, fn);
}
- } else if(!strcmp(server->protocol, "http") || pmo_proxyhost) {
- char src[PATH_MAX];
- char *host;
- unsigned port;
- if(!strcmp(server->protocol, "http") && !pmo_proxyhost) {
- /* HTTP servers hang up after each request (but not proxies), so
- * we have to re-connect for each files.
- */
- host = (pmo_proxyhost) ? pmo_proxyhost : server->server;
- port = (pmo_proxyhost) ? pmo_proxyport : 80;
- if(strchr(host, ':')) {
- vprint("Connecting to %s\n", host);
- } else {
- vprint("Connecting to %s:%u\n", host, port);
+ chdir(cwd);
+ } else {
+ char output[PATH_MAX];
+ int j, filedone = 0;
+ char *ptr;
+ struct stat st;
+ snprintf(output, PATH_MAX, "%s/%s.part", localpath, fn);
+ strncpy(sync_fnm, fn, 24);
+ /* drop filename extension */
+ ptr = strstr(fn, ".db.tar.gz");
+ if(ptr && (ptr-fn) < 24) {
+ sync_fnm[ptr-fn] = '\0';
+ }
+ ptr = strstr(fn, ".pkg.tar.gz");
+ if(ptr && (ptr-fn) < 24) {
+ sync_fnm[ptr-fn] = '\0';
+ }
+ for(j = strlen(sync_fnm); j < 24; j++) {
+ sync_fnm[j] = ' ';
+ }
+ sync_fnm[24] = '\0';
+ offset = 0;
+
+ /* ETA setup */
+ gettimeofday(&t0, NULL);
+ t = t0;
+ rate = 0;
+ xfered1 = 0;
+ eta_h = 0;
+ eta_m = 0;
+ eta_s = 0;
+
+ if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) {
+ 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);
+ }
}
- if(!HttpConnect(host, port, &control)) {
- fprintf(stderr, "error: cannot connect to %s\n", host);
- continue;
+ 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;
}
- /* set up our progress bar's callback (and idle timeout) */
- if(strcmp(server->protocol, "file") && control) {
- FtpOptions(FTPLIB_CALLBACK, (long)log_progress, control);
- FtpOptions(FTPLIB_IDLETIME, (long)1000, control);
- FtpOptions(FTPLIB_CALLBACKARG, (long)&fsz, control);
- FtpOptions(FTPLIB_CALLBACKBYTES, (10*1024), control);
+ } else if(!strcmp(server->protocol, "http") || pmo_proxyhost) {
+ char src[PATH_MAX];
+ char *host;
+ unsigned port;
+ if(!strcmp(server->protocol, "http") && !pmo_proxyhost) {
+ /* HTTP servers hang up after each request (but not proxies), so
+ * we have to re-connect for each file.
+ */
+ host = (pmo_proxyhost) ? pmo_proxyhost : server->server;
+ port = (pmo_proxyhost) ? pmo_proxyport : 80;
+ if(strchr(host, ':')) {
+ vprint("Connecting to %s\n", host);
+ } else {
+ vprint("Connecting to %s:%u\n", host, port);
+ }
+ if(!HttpConnect(host, port, &control)) {
+ fprintf(stderr, "error: cannot connect to %s\n", host);
+ continue;
+ }
+ /* set up our progress bar's callback (and idle timeout) */
+ if(strcmp(server->protocol, "file") && control) {
+ FtpOptions(FTPLIB_CALLBACK, (long)log_progress, control);
+ FtpOptions(FTPLIB_IDLETIME, (long)1000, control);
+ FtpOptions(FTPLIB_CALLBACKARG, (long)&fsz, control);
+ FtpOptions(FTPLIB_CALLBACKBYTES, (10*1024), control);
+ }
}
- }
- if(!stat(output, &st)) {
- offset = (int)st.st_size;
- }
- if(!pmo_proxyhost) {
+ if(!stat(output, &st)) {
+ offset = (int)st.st_size;
+ }
+ if(!pmo_proxyhost) {
+ snprintf(src, PATH_MAX, "%s%s", server->path, fn);
+ } else {
+ snprintf(src, PATH_MAX, "%s://%s%s%s", server->protocol, server->server, server->path, fn);
+ }
+ if(!HttpGet(server->server, output, src, &fsz, control, offset)) {
+ 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, "file")) {
+ char src[PATH_MAX];
snprintf(src, PATH_MAX, "%s%s", server->path, fn);
- } else {
- snprintf(src, PATH_MAX, "%s://%s%s%s", server->protocol, server->server, server->path, fn);
- }
- if(!HttpGet(server->server, output, src, &fsz, control, offset)) {
- 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, "file")) {
- char src[PATH_MAX];
- snprintf(src, PATH_MAX, "%s%s", server->path, fn);
- vprint("copying %s to %s/%s\n", src, localpath, fn);
- /* local repository, just copy the file */
- if(copyfile(src, output)) {
- fprintf(stderr, "failed copying %s\n", src);
- } else {
- filedone = 1;
+ vprint("copying %s to %s/%s\n", src, localpath, fn);
+ /* local repository, just copy the file */
+ if(copyfile(src, output)) {
+ fprintf(stderr, "failed copying %s\n", src);
+ } else {
+ filedone = 1;
+ }
}
- }
- if(filedone) {
- char completefile[PATH_MAX];
- if(!strcmp(server->protocol, "file")) {
- char out[56];
- printf(" %s [", sync_fnm);
- strncpy(out, server->path, 33);
- printf("%s", out);
- for(j = strlen(out); j < maxcols-64; j++) {
- printf(" ");
+ if(filedone) {
+ char completefile[PATH_MAX];
+ if(!strcmp(server->protocol, "file")) {
+ char out[56];
+ printf(" %s [", sync_fnm);
+ strncpy(out, server->path, 33);
+ printf("%s", out);
+ for(j = strlen(out); j < maxcols-64; j++) {
+ printf(" ");
+ }
+ fputs("] 100% | LOCAL |", stdout);
+ } else {
+ log_progress(control, fsz-offset, &fsz);
}
- fputs("] 100% | LOCAL |", stdout);
- } else {
- log_progress(control, fsz-offset, &fsz);
+ complete = list_add(complete, fn);
+ /* rename "output.part" file to "output" file */
+ snprintf(completefile, PATH_MAX, "%s/%s", localpath, fn);
+ rename(output, completefile);
}
- complete = list_add(complete, fn);
- /* rename "output.part" file to "output" file */
- snprintf(completefile, PATH_MAX, "%s/%s", localpath, fn);
- rename(output, completefile);
+ printf("\n");
+ fflush(stdout);
}
- printf("\n");
- fflush(stdout);
}
- if(list_count(complete) == list_count(files)) {
- done = 1;
+ if(!pmo_xfercommand) {
+ if(!strcmp(server->protocol, "ftp")) {
+ FtpQuit(control);
+ } else if(!strcmp(server->protocol, "http")) {
+ HttpQuit(control);
+ }
}
- if(!strcmp(server->protocol, "ftp")) {
- FtpQuit(control);
- } else if(!strcmp(server->protocol, "http")) {
- HttpQuit(control);
+ if(list_count(complete) == list_count(files)) {
+ done = 1;
}
}