file.c revision 67892
1/*-
2 * Copyright (c) 1998 Dag-Erling Co�dan Sm�rgrav
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer
10 *    in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: head/lib/libfetch/file.c 67892 2000-10-29 15:56:10Z des $
29 */
30
31#include <sys/param.h>
32#include <sys/stat.h>
33
34#include <dirent.h>
35#include <stdio.h>
36#include <string.h>
37
38#include "fetch.h"
39#include "common.h"
40
41FILE *
42fetchXGetFile(struct url *u, struct url_stat *us, char *flags)
43{
44    FILE *f;
45
46    if (us && fetchStatFile(u, us, flags) == -1)
47	return NULL;
48
49    f = fopen(u->doc, "r");
50
51    if (f == NULL)
52	_fetch_syserr();
53
54    if (u->offset && fseek(f, u->offset, SEEK_SET) == -1) {
55	fclose(f);
56	_fetch_syserr();
57    }
58
59    return f;
60}
61
62FILE *
63fetchGetFile(struct url *u, char *flags)
64{
65    return fetchXGetFile(u, NULL, flags);
66}
67
68FILE *
69fetchPutFile(struct url *u, char *flags)
70{
71    FILE *f;
72
73    if (CHECK_FLAG('a'))
74	f = fopen(u->doc, "a");
75    else
76	f = fopen(u->doc, "w+");
77
78    if (f == NULL)
79	_fetch_syserr();
80
81    if (u->offset && fseek(f, u->offset, SEEK_SET) == -1) {
82	fclose(f);
83	_fetch_syserr();
84    }
85
86    return f;
87}
88
89static int
90_fetch_stat_file(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, char *flags)
108{
109    return _fetch_stat_file(u->doc, us);
110}
111
112struct url_ent *
113fetchListFile(struct url *u, 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[MAXPATHLEN], *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