file.c revision 77237
1236769Sobrien/*- 2236769Sobrien * Copyright (c) 1998 Dag-Erling Co�dan Sm�rgrav 3236769Sobrien * All rights reserved. 4236769Sobrien * 5236769Sobrien * Redistribution and use in source and binary forms, with or without 6236769Sobrien * modification, are permitted provided that the following conditions 7236769Sobrien * are met: 8236769Sobrien * 1. Redistributions of source code must retain the above copyright 9236769Sobrien * notice, this list of conditions and the following disclaimer 10236769Sobrien * in this position and unchanged. 11236769Sobrien * 2. Redistributions in binary form must reproduce the above copyright 12236769Sobrien * notice, this list of conditions and the following disclaimer in the 13236769Sobrien * documentation and/or other materials provided with the distribution. 14236769Sobrien * 3. The name of the author may not be used to endorse or promote products 15236769Sobrien * derived from this software without specific prior written permission 16236769Sobrien * 17236769Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18236769Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19236769Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20236769Sobrien * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21236769Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22236769Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23236769Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24236769Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25236769Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26236769Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27236769Sobrien * 28236769Sobrien * $FreeBSD: head/lib/libfetch/file.c 77237 2001-05-26 19:36:49Z des $ 29236769Sobrien */ 30236769Sobrien 31236769Sobrien#include <sys/param.h> 32236769Sobrien#include <sys/stat.h> 33236769Sobrien 34236769Sobrien#include <dirent.h> 35236769Sobrien#include <stdio.h> 36236769Sobrien#include <string.h> 37236769Sobrien 38236769Sobrien#include "fetch.h" 39236769Sobrien#include "common.h" 40236769Sobrien 41236769SobrienFILE * 42236769SobrienfetchXGetFile(struct url *u, struct url_stat *us, const char *flags) 43236769Sobrien{ 44236769Sobrien FILE *f; 45236769Sobrien 46236769Sobrien if (us && fetchStatFile(u, us, flags) == -1) 47236769Sobrien return NULL; 48236769Sobrien 49236769Sobrien f = fopen(u->doc, "r"); 50236769Sobrien 51236769Sobrien if (f == NULL) 52236769Sobrien _fetch_syserr(); 53236769Sobrien 54236769Sobrien if (u->offset && fseek(f, u->offset, SEEK_SET) == -1) { 55236769Sobrien fclose(f); 56236769Sobrien _fetch_syserr(); 57236769Sobrien } 58236769Sobrien 59236769Sobrien return f; 60236769Sobrien} 61236769Sobrien 62236769SobrienFILE * 63236769SobrienfetchGetFile(struct url *u, const char *flags) 64236769Sobrien{ 65236769Sobrien return fetchXGetFile(u, NULL, flags); 66236769Sobrien} 67236769Sobrien 68236769SobrienFILE * 69236769SobrienfetchPutFile(struct url *u, const char *flags) 70236769Sobrien{ 71236769Sobrien FILE *f; 72236769Sobrien 73236769Sobrien if (CHECK_FLAG('a')) 74236769Sobrien f = fopen(u->doc, "a"); 75236769Sobrien else 76236769Sobrien f = fopen(u->doc, "w+"); 77236769Sobrien 78236769Sobrien if (f == NULL) 79236769Sobrien _fetch_syserr(); 80236769Sobrien 81236769Sobrien if (u->offset && fseek(f, u->offset, SEEK_SET) == -1) { 82236769Sobrien fclose(f); 83236769Sobrien _fetch_syserr(); 84236769Sobrien } 85236769Sobrien 86236769Sobrien return f; 87236769Sobrien} 88 89static int 90_fetch_stat_file(const char *fn, struct url_stat *us) 91{ 92 struct stat sb; 93 94 us->size = -1; 95 us->atime = us->mtime = 0; 96 if (stat(fn, &sb) == -1) { 97 _fetch_syserr(); 98 return -1; 99 } 100 us->size = sb.st_size; 101 us->atime = sb.st_atime; 102 us->mtime = sb.st_mtime; 103 return 0; 104} 105 106int 107fetchStatFile(struct url *u, struct url_stat *us, const char *flags) 108{ 109 return _fetch_stat_file(u->doc, us); 110} 111 112struct url_ent * 113fetchListFile(struct url *u, const char *flags) 114{ 115 DIR *dir; 116 struct dirent *de; 117 struct url_stat us; 118 struct url_ent *ue; 119 int size, len; 120 char fn[PATH_MAX], *p; 121 int l; 122 123 if ((dir = opendir(u->doc)) == NULL) { 124 _fetch_syserr(); 125 return NULL; 126 } 127 128 ue = NULL; 129 strncpy(fn, u->doc, sizeof fn - 2); 130 fn[sizeof fn - 2] = 0; 131 strcat(fn, "/"); 132 p = strchr(fn, 0); 133 l = sizeof fn - strlen(fn) - 1; 134 135 while ((de = readdir(dir)) != NULL) { 136 strncpy(p, de->d_name, l - 1); 137 p[l - 1] = 0; 138 if (_fetch_stat_file(fn, &us) == -1) 139 /* should I return a partial result, or abort? */ 140 break; 141 _fetch_add_entry(&ue, &size, &len, de->d_name, &us); 142 } 143 144 return ue; 145} 146