14ca1ab94SDag-Erling Smørgrav /*- 2*578153f1SDag-Erling Smørgrav * Copyright (c) 1998-2011 Dag-Erling Smørgrav 34ca1ab94SDag-Erling Smørgrav * All rights reserved. 44ca1ab94SDag-Erling Smørgrav * 54ca1ab94SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 64ca1ab94SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 74ca1ab94SDag-Erling Smørgrav * are met: 84ca1ab94SDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 94ca1ab94SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer 104ca1ab94SDag-Erling Smørgrav * in this position and unchanged. 114ca1ab94SDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 124ca1ab94SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 134ca1ab94SDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 144ca1ab94SDag-Erling Smørgrav * 3. The name of the author may not be used to endorse or promote products 154ca1ab94SDag-Erling Smørgrav * derived from this software without specific prior written permission 164ca1ab94SDag-Erling Smørgrav * 174ca1ab94SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 184ca1ab94SDag-Erling Smørgrav * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 194ca1ab94SDag-Erling Smørgrav * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 204ca1ab94SDag-Erling Smørgrav * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 214ca1ab94SDag-Erling Smørgrav * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 224ca1ab94SDag-Erling Smørgrav * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234ca1ab94SDag-Erling Smørgrav * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244ca1ab94SDag-Erling Smørgrav * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254ca1ab94SDag-Erling Smørgrav * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 264ca1ab94SDag-Erling Smørgrav * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274ca1ab94SDag-Erling Smørgrav */ 284ca1ab94SDag-Erling Smørgrav 29cecb889fSMatthew Dillon #include <sys/cdefs.h> 30cecb889fSMatthew Dillon __FBSDID("$FreeBSD$"); 31cecb889fSMatthew Dillon 320fba3a00SDag-Erling Smørgrav #include <sys/param.h> 33d8acd8dcSDag-Erling Smørgrav #include <sys/stat.h> 34ce71b736SDag-Erling Smørgrav 35ce71b736SDag-Erling Smørgrav #include <dirent.h> 3615b68c63SDag-Erling Smørgrav #include <fcntl.h> 374ca1ab94SDag-Erling Smørgrav #include <stdio.h> 384ca1ab94SDag-Erling Smørgrav #include <string.h> 394ca1ab94SDag-Erling Smørgrav 404ca1ab94SDag-Erling Smørgrav #include "fetch.h" 41d8acd8dcSDag-Erling Smørgrav #include "common.h" 424ca1ab94SDag-Erling Smørgrav 434ca1ab94SDag-Erling Smørgrav FILE * 4438c7e4a6SArchie Cobbs fetchXGetFile(struct url *u, struct url_stat *us, const char *flags) 454ca1ab94SDag-Erling Smørgrav { 46d8acd8dcSDag-Erling Smørgrav FILE *f; 47d8acd8dcSDag-Erling Smørgrav 481a5faa10SDag-Erling Smørgrav if (us && fetchStatFile(u, us, flags) == -1) 49e19e6098SDag-Erling Smørgrav return (NULL); 501a5faa10SDag-Erling Smørgrav 51d8acd8dcSDag-Erling Smørgrav f = fopen(u->doc, "r"); 52d8acd8dcSDag-Erling Smørgrav 53d8acd8dcSDag-Erling Smørgrav if (f == NULL) 54a1b37df2SDag-Erling Smørgrav fetch_syserr(); 555ff28c82SDag-Erling Smørgrav 5698b8c4cbSDag-Erling Smørgrav if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) { 575ff28c82SDag-Erling Smørgrav fclose(f); 58a1b37df2SDag-Erling Smørgrav fetch_syserr(); 595ff28c82SDag-Erling Smørgrav } 605ff28c82SDag-Erling Smørgrav 6115b68c63SDag-Erling Smørgrav fcntl(fileno(f), F_SETFD, FD_CLOEXEC); 62e19e6098SDag-Erling Smørgrav return (f); 634ca1ab94SDag-Erling Smørgrav } 644ca1ab94SDag-Erling Smørgrav 654ca1ab94SDag-Erling Smørgrav FILE * 6638c7e4a6SArchie Cobbs fetchGetFile(struct url *u, const char *flags) 671a5faa10SDag-Erling Smørgrav { 68e19e6098SDag-Erling Smørgrav return (fetchXGetFile(u, NULL, flags)); 691a5faa10SDag-Erling Smørgrav } 701a5faa10SDag-Erling Smørgrav 711a5faa10SDag-Erling Smørgrav FILE * 7238c7e4a6SArchie Cobbs fetchPutFile(struct url *u, const char *flags) 734ca1ab94SDag-Erling Smørgrav { 74d8acd8dcSDag-Erling Smørgrav FILE *f; 75d8acd8dcSDag-Erling Smørgrav 76d74a913bSDag-Erling Smørgrav if (CHECK_FLAG('a')) 77d8acd8dcSDag-Erling Smørgrav f = fopen(u->doc, "a"); 78d8acd8dcSDag-Erling Smørgrav else 795ff28c82SDag-Erling Smørgrav f = fopen(u->doc, "w+"); 80d8acd8dcSDag-Erling Smørgrav 81d8acd8dcSDag-Erling Smørgrav if (f == NULL) 82a1b37df2SDag-Erling Smørgrav fetch_syserr(); 835ff28c82SDag-Erling Smørgrav 8498b8c4cbSDag-Erling Smørgrav if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) { 855ff28c82SDag-Erling Smørgrav fclose(f); 86a1b37df2SDag-Erling Smørgrav fetch_syserr(); 875ff28c82SDag-Erling Smørgrav } 885ff28c82SDag-Erling Smørgrav 8915b68c63SDag-Erling Smørgrav fcntl(fileno(f), F_SETFD, FD_CLOEXEC); 90e19e6098SDag-Erling Smørgrav return (f); 91d8acd8dcSDag-Erling Smørgrav } 92d8acd8dcSDag-Erling Smørgrav 93ce71b736SDag-Erling Smørgrav static int 94a1b37df2SDag-Erling Smørgrav fetch_stat_file(const char *fn, struct url_stat *us) 95d8acd8dcSDag-Erling Smørgrav { 96d8acd8dcSDag-Erling Smørgrav struct stat sb; 97d8acd8dcSDag-Erling Smørgrav 987a5b4b1bSDag-Erling Smørgrav us->size = -1; 997a5b4b1bSDag-Erling Smørgrav us->atime = us->mtime = 0; 100ce71b736SDag-Erling Smørgrav if (stat(fn, &sb) == -1) { 101a1b37df2SDag-Erling Smørgrav fetch_syserr(); 102e19e6098SDag-Erling Smørgrav return (-1); 103d8acd8dcSDag-Erling Smørgrav } 104d8acd8dcSDag-Erling Smørgrav us->size = sb.st_size; 1050fba3a00SDag-Erling Smørgrav us->atime = sb.st_atime; 1060fba3a00SDag-Erling Smørgrav us->mtime = sb.st_mtime; 107e19e6098SDag-Erling Smørgrav return (0); 1084ca1ab94SDag-Erling Smørgrav } 109ce71b736SDag-Erling Smørgrav 110ce71b736SDag-Erling Smørgrav int 11198b8c4cbSDag-Erling Smørgrav fetchStatFile(struct url *u, struct url_stat *us, const char *flags __unused) 112ce71b736SDag-Erling Smørgrav { 113a1b37df2SDag-Erling Smørgrav return (fetch_stat_file(u->doc, us)); 114ce71b736SDag-Erling Smørgrav } 115ce71b736SDag-Erling Smørgrav 116ce71b736SDag-Erling Smørgrav struct url_ent * 11798b8c4cbSDag-Erling Smørgrav fetchListFile(struct url *u, const char *flags __unused) 118ce71b736SDag-Erling Smørgrav { 119ce71b736SDag-Erling Smørgrav struct dirent *de; 120ce71b736SDag-Erling Smørgrav struct url_stat us; 121ce71b736SDag-Erling Smørgrav struct url_ent *ue; 122ce71b736SDag-Erling Smørgrav int size, len; 1232b26f942SDag-Erling Smørgrav char fn[PATH_MAX], *p; 124e19e6098SDag-Erling Smørgrav DIR *dir; 125ce71b736SDag-Erling Smørgrav int l; 126ce71b736SDag-Erling Smørgrav 127ce71b736SDag-Erling Smørgrav if ((dir = opendir(u->doc)) == NULL) { 128a1b37df2SDag-Erling Smørgrav fetch_syserr(); 129e19e6098SDag-Erling Smørgrav return (NULL); 130ce71b736SDag-Erling Smørgrav } 131ce71b736SDag-Erling Smørgrav 132ce71b736SDag-Erling Smørgrav ue = NULL; 133930105c1SDag-Erling Smørgrav strncpy(fn, u->doc, sizeof(fn) - 2); 134930105c1SDag-Erling Smørgrav fn[sizeof(fn) - 2] = 0; 135ce71b736SDag-Erling Smørgrav strcat(fn, "/"); 136ce71b736SDag-Erling Smørgrav p = strchr(fn, 0); 137930105c1SDag-Erling Smørgrav l = sizeof(fn) - strlen(fn) - 1; 138ce71b736SDag-Erling Smørgrav 139ce71b736SDag-Erling Smørgrav while ((de = readdir(dir)) != NULL) { 140ce71b736SDag-Erling Smørgrav strncpy(p, de->d_name, l - 1); 141ce71b736SDag-Erling Smørgrav p[l - 1] = 0; 142a1b37df2SDag-Erling Smørgrav if (fetch_stat_file(fn, &us) == -1) 143ce71b736SDag-Erling Smørgrav /* should I return a partial result, or abort? */ 144ce71b736SDag-Erling Smørgrav break; 145a1b37df2SDag-Erling Smørgrav fetch_add_entry(&ue, &size, &len, de->d_name, &us); 146ce71b736SDag-Erling Smørgrav } 147ce71b736SDag-Erling Smørgrav 148e19e6098SDag-Erling Smørgrav return (ue); 149ce71b736SDag-Erling Smørgrav } 150