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