]> pd.if.org Git - zpackage/commitdiff
add options for fetchurl
authorNathan Wagner <nw@hydaspes.if.org>
Sat, 16 Feb 2019 15:52:11 +0000 (15:52 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Sat, 16 Feb 2019 15:52:11 +0000 (15:52 +0000)
crypto/rfc3986.re
doc/zpm-fetchurl.8
src/fetchurl.c

index 463486f6968549138fd98c5a5b2476b1dd4434dc..feaf49ac0340942c92700db180b867c49ce4d61b 100644 (file)
@@ -205,7 +205,6 @@ int tls_parse_uri(char *s, struct tls_uri *uri) {
        percent_decode(uri->host);
        percent_decode(uri->path);
        percent_decode(uri->query);
        percent_decode(uri->host);
        percent_decode(uri->path);
        percent_decode(uri->query);
-
        
        if (uri->path == NULL || uri->path[0] == 0) {
                free(uri->path);
        
        if (uri->path == NULL || uri->path[0] == 0) {
                free(uri->path);
@@ -215,10 +214,21 @@ int tls_parse_uri(char *s, struct tls_uri *uri) {
        return rv;
 }
 
        return rv;
 }
 
+#define MARK fprintf(stderr, "%s %s:%d\n", __FILE__, __func__, __LINE__)
 void tls_free_uri(struct tls_uri *uri) {
 void tls_free_uri(struct tls_uri *uri) {
+       if (!uri) return;
+
        free(uri->host);
        free(uri->host);
+       uri->host = 0;
        free(uri->path);
        free(uri->path);
+       uri->path = 0;
        free(uri->query);
        free(uri->query);
+       uri->query = 0;
        free(uri->port);
        free(uri->port);
+       uri->port = 0;
        free(uri->scheme);
        free(uri->scheme);
+       uri->scheme = 0;
+       free(uri->fragment);
+       uri->fragment = 0;
+       
 }
 }
index 4a269b394f7aeaf042695d8c14629c4cc95e0092..8f9385990083b276214df5642fe636be0c6ea68b 100644 (file)
@@ -1,10 +1,10 @@
-.TH zpm-fetchurl 8 2019-02-15 "ZPM 0.4"
+.TH zpm-fetchurl 8 2019-02-16 "ZPM 0.4"
 .SH NAME
 zpm-fetchurl \- download files
 .SH SYNOPSIS
 .B zpm fetchurl
 [
 .SH NAME
 zpm-fetchurl \- download files
 .SH SYNOPSIS
 .B zpm fetchurl
 [
-.B -ISkKr
+.B -ISkKrOn
 ]
 [
 .BI -o file
 ]
 [
 .BI -o file
@@ -51,6 +51,12 @@ Only download if remote is newer than the file given by path
 Write the output to the file given by \fIpath\fR.  Output is
 written to stdout by default.
 .TP
 Write the output to the file given by \fIpath\fR.  Output is
 written to stdout by default.
 .TP
+.B \-O
+Calculate the output file name from the url.
+.TP
+.B \-n
+Only if newer.  Like \-z, except use the output file name, if any.
+.TP
 .B \-f
 Fail silently on errors.
 .TP
 .B \-f
 Fail silently on errors.
 .TP
index 9d526961f32afbd9cee6f999605be2f96e9670ee..395ce9573f5f444c61c1c2a66860e639864d12eb 100644 (file)
@@ -539,6 +539,22 @@ char *pathlast(char *path) {
        return strndup(last, len);
 }
 
        return strndup(last, len);
 }
 
+static time_t file_mtime(char *path) {
+       struct stat st;
+       int rv;
+
+       rv = stat(path, &st);
+       if (rv == -1) {
+               if (errno == ENOENT) {
+                       return 0;
+               } 
+               perror("stat failed:");
+               return -1;
+       }
+
+       return st.st_mtime;
+}
+
 int main(int ac, char *av[]) {
        int sockfd, port = -1, rv;
        ssize_t ret;
 int main(int ac, char *av[]) {
        int sockfd, port = -1, rv;
        ssize_t ret;
@@ -553,7 +569,7 @@ int main(int ac, char *av[]) {
        struct tls_uri uri = { 0 };
        char *outfile = 0;
        int raw = 0, head = 0;
        struct tls_uri uri = { 0 };
        char *outfile = 0;
        int raw = 0, head = 0;
-       int out = 1;
+       int out = 1; /* output file descriptor */
        int use_tls = 0;
        struct io io = { {0}, 0, -1, 0, 0, 0, 0, 0 };
        struct TLSContext *clientssl = 0;
        int use_tls = 0;
        struct io io = { {0}, 0, -1, 0, 0, 0, 0, 0 };
        struct TLSContext *clientssl = 0;
@@ -567,11 +583,11 @@ int main(int ac, char *av[]) {
        size_t header_len;
        char *url = 0;
        int redirs = 0, redirlimit = 50, printstatus = 0;
        size_t header_len;
        char *url = 0;
        int redirs = 0, redirlimit = 50, printstatus = 0;
-       int verifypolicy = 1, calcoutfile = 0;
+       int verifypolicy = 1, calcoutfile = 0, ifnewer = 0;
 
        ltc_mp = tfm_desc;
 
 
        ltc_mp = tfm_desc;
 
-       while ((option = getopt(ac, av, "o:OrIfz:#R:SkK")) != -1) {
+       while ((option = getopt(ac, av, "o:OrIfz:n#R:SkK")) != -1) {
                switch (option) {
                        case 'o': outfile = optarg; break;
                        case 'O': calcoutfile = 1; break;
                switch (option) {
                        case 'o': outfile = optarg; break;
                        case 'O': calcoutfile = 1; break;
@@ -582,6 +598,7 @@ int main(int ac, char *av[]) {
                        case 'r': raw = 1; break;
                        case 'f': failsilent = 1; break;
                        case 'z': lmfile = optarg; break;
                        case 'r': raw = 1; break;
                        case 'f': failsilent = 1; break;
                        case 'z': lmfile = optarg; break;
+                       case 'n': ifnewer = 1; break;
                        case 'R': redirlimit = strtol(optarg, 0, 10); break;
                        case '#': progressbar = 1; break;
                        default:
                        case 'R': redirlimit = strtol(optarg, 0, 10); break;
                        case '#': progressbar = 1; break;
                        default:
@@ -595,29 +612,13 @@ int main(int ac, char *av[]) {
                exit(EXIT_FAILURE);
        }
 
                exit(EXIT_FAILURE);
        }
 
-       io.last_modified = 0;
-       if (lmfile) {
-               struct stat st;
-               int rv;
-               struct tm *mtime;
-               time_t ts;
-
-               rv = stat(lmfile, &st);
-               if (rv == -1) {
-                       perror("stat failed:");
-                       exit(EXIT_FAILURE);
-               }
-               ts = st.st_mtime;
-               io.last_modified = ts;
-               mtime = gmtime(&ts);
-               strftime(lmtime, sizeof lmtime, "%a, %d %b %Y %H:%M:%S GMT", mtime);
-       }
-
        url = strdup(av[optind]);
        if (!url) {
                exit(EXIT_FAILURE);
        }
 
        url = strdup(av[optind]);
        if (!url) {
                exit(EXIT_FAILURE);
        }
 
+       io.last_modified = 0;
+
        if (calcoutfile && !outfile) {
                tls_parse_uri(url, &uri);
                outfile = pathlast(uri.path);
        if (calcoutfile && !outfile) {
                tls_parse_uri(url, &uri);
                outfile = pathlast(uri.path);
@@ -631,11 +632,24 @@ int main(int ac, char *av[]) {
                }
        }
 
                }
        }
 
-       if (outfile) {
-               out = open(outfile, O_WRONLY|O_CREAT, 0600);
-               if (out == -1) {
-                       perror("can't open output file:");
+       if (ifnewer && outfile && !lmfile) {
+               lmfile = outfile;
+       }
+
+       if (lmfile) {
+               struct tm *mtime;
+               time_t ts;
+
+               ts = file_mtime(lmfile);
+
+               if (ts == -1) {
                        exit(EXIT_FAILURE);
                        exit(EXIT_FAILURE);
+               } else if (ts != 0) {
+                       io.last_modified = ts;
+                       mtime = gmtime(&ts);
+                       strftime(lmtime, sizeof lmtime, "%a, %d %b %Y %H:%M:%S GMT", mtime);
+               } else {
+                       lmfile = 0;
                }
        }
 
                }
        }
 
@@ -648,13 +662,13 @@ int main(int ac, char *av[]) {
                tls_free_uri(&uri);
                io.response.len = 0;
                request.len = 0;
                tls_free_uri(&uri);
                io.response.len = 0;
                request.len = 0;
+               eoh = 0;
 
                tls_parse_uri(url, &uri);
                host = uri.host;
                port = atoi(uri.port);
                req_file = uri.path;
 
 
                tls_parse_uri(url, &uri);
                host = uri.host;
                port = atoi(uri.port);
                req_file = uri.path;
 
-
                /* construct request */
                if (head) {
                        tls_buffer_append(&request, "HEAD ", 5);
                /* construct request */
                if (head) {
                        tls_buffer_append(&request, "HEAD ", 5);
@@ -762,12 +776,15 @@ int main(int ac, char *av[]) {
                parse_header(&io);
 
                switch (io.status_code) {
                parse_header(&io);
 
                switch (io.status_code) {
+                       case 304:
+                               break;
                        case 301:
                        case 302:
                        case 303:
                        case 307:
                                free(url);
                                url = strdup(io.redirect);
                        case 301:
                        case 302:
                        case 303:
                        case 307:
                                free(url);
                                url = strdup(io.redirect);
+                               close(io.socket);
                                continue;
                                break;
                }
                                continue;
                                break;
                }
@@ -790,6 +807,14 @@ int main(int ac, char *av[]) {
                        }
                }
 
                        }
                }
 
+               if (outfile) {
+                       out = open(outfile, O_WRONLY|O_CREAT, 0600);
+                       if (out == -1) {
+                               perror("can't open output file:");
+                               exit(EXIT_FAILURE);
+                       }
+               }
+
                do {
                        write(out, io.response.buffer, io.response.len);
                        ret = io.response.len;
                do {
                        write(out, io.response.buffer, io.response.len);
                        ret = io.response.len;
@@ -817,7 +842,12 @@ int main(int ac, char *av[]) {
                if (ret < 0) {
                        fprintf(stderr, "%s read error %zd\n", uri.scheme, ret);
                }
                if (ret < 0) {
                        fprintf(stderr, "%s read error %zd\n", uri.scheme, ret);
                }
-               /* futimens(out, ...) */
+               struct timespec ts[2];
+               ts[0].tv_sec = 0; ts[0].tv_nsec = UTIME_OMIT;
+               ts[1].tv_sec = io.last_modified;
+               ts[1].tv_nsec = 0;
+
+               futimens(out, ts);
                close(out);
                tls_buffer_free(&io.response);
                break;
                close(out);
                tls_buffer_free(&io.response);
                break;
@@ -834,5 +864,5 @@ int main(int ac, char *av[]) {
                putc('\n',stderr);
        }
 
                putc('\n',stderr);
        }
 
-       return io.status_code == 200 ? 0 : EXIT_FAILURE;
+       return io.status_code < 400 ? 0 : EXIT_FAILURE;
 }
 }