file.c revision 174588
137535Sdes/*-
2135546Sdes * Copyright (c) 1998-2004 Dag-Erling Co�dan Sm�rgrav
337535Sdes * All rights reserved.
437535Sdes *
537535Sdes * Redistribution and use in source and binary forms, with or without
637535Sdes * modification, are permitted provided that the following conditions
737535Sdes * are met:
837535Sdes * 1. Redistributions of source code must retain the above copyright
937535Sdes *    notice, this list of conditions and the following disclaimer
1037535Sdes *    in this position and unchanged.
1137535Sdes * 2. Redistributions in binary form must reproduce the above copyright
1237535Sdes *    notice, this list of conditions and the following disclaimer in the
1337535Sdes *    documentation and/or other materials provided with the distribution.
1437535Sdes * 3. The name of the author may not be used to endorse or promote products
1537535Sdes *    derived from this software without specific prior written permission
1637535Sdes *
1737535Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1837535Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1937535Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2037535Sdes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2137535Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2237535Sdes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2337535Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2437535Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2537535Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2637535Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2737535Sdes */
2837535Sdes
2984203Sdillon#include <sys/cdefs.h>
3084203Sdillon__FBSDID("$FreeBSD: head/lib/libfetch/file.c 174588 2007-12-14 10:26:58Z des $");
3184203Sdillon
3241862Sdes#include <sys/param.h>
3340975Sdes#include <sys/stat.h>
3441989Sdes
3541989Sdes#include <dirent.h>
3637535Sdes#include <stdio.h>
3737535Sdes#include <string.h>
3837535Sdes
3937535Sdes#include "fetch.h"
4040975Sdes#include "common.h"
4137535Sdes
4237535SdesFILE *
4375891SarchiefetchXGetFile(struct url *u, struct url_stat *us, const char *flags)
4437535Sdes{
4590267Sdes	FILE *f;
4660187Sdes
4790267Sdes	if (us && fetchStatFile(u, us, flags) == -1)
4890267Sdes		return (NULL);
4990267Sdes
5090267Sdes	f = fopen(u->doc, "r");
5190267Sdes
5290267Sdes	if (f == NULL)
53174588Sdes		fetch_syserr();
5490267Sdes
5590267Sdes	if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) {
5690267Sdes		fclose(f);
57174588Sdes		fetch_syserr();
5890267Sdes	}
5990267Sdes
6090267Sdes	return (f);
6137535Sdes}
6237535Sdes
6337535SdesFILE *
6475891SarchiefetchGetFile(struct url *u, const char *flags)
6563340Sdes{
6690267Sdes	return (fetchXGetFile(u, NULL, flags));
6763340Sdes}
6863340Sdes
6963340SdesFILE *
7075891SarchiefetchPutFile(struct url *u, const char *flags)
7137535Sdes{
7290267Sdes	FILE *f;
7390267Sdes
7490267Sdes	if (CHECK_FLAG('a'))
7590267Sdes		f = fopen(u->doc, "a");
7690267Sdes	else
7790267Sdes		f = fopen(u->doc, "w+");
7890267Sdes
7990267Sdes	if (f == NULL)
80174588Sdes		fetch_syserr();
8190267Sdes
8290267Sdes	if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) {
8390267Sdes		fclose(f);
84174588Sdes		fetch_syserr();
8590267Sdes	}
8690267Sdes
8790267Sdes	return (f);
8837535Sdes}
8940975Sdes
9041989Sdesstatic int
91174588Sdesfetch_stat_file(const char *fn, struct url_stat *us)
9240975Sdes{
9390267Sdes	struct stat sb;
9440975Sdes
9590267Sdes	us->size = -1;
9690267Sdes	us->atime = us->mtime = 0;
9790267Sdes	if (stat(fn, &sb) == -1) {
98174588Sdes		fetch_syserr();
9990267Sdes		return (-1);
10090267Sdes	}
10190267Sdes	us->size = sb.st_size;
10290267Sdes	us->atime = sb.st_atime;
10390267Sdes	us->mtime = sb.st_mtime;
10490267Sdes	return (0);
10540975Sdes}
10641989Sdes
10741989Sdesint
10883076SdesfetchStatFile(struct url *u, struct url_stat *us, const char *flags __unused)
10941989Sdes{
110174588Sdes	return (fetch_stat_file(u->doc, us));
11141989Sdes}
11241989Sdes
11341989Sdesstruct url_ent *
11483076SdesfetchListFile(struct url *u, const char *flags __unused)
11541989Sdes{
11690267Sdes	struct dirent *de;
11790267Sdes	struct url_stat us;
11890267Sdes	struct url_ent *ue;
11990267Sdes	int size, len;
12090267Sdes	char fn[PATH_MAX], *p;
12190267Sdes	DIR *dir;
12290267Sdes	int l;
12341989Sdes
12490267Sdes	if ((dir = opendir(u->doc)) == NULL) {
125174588Sdes		fetch_syserr();
12690267Sdes		return (NULL);
12790267Sdes	}
12841989Sdes
12990267Sdes	ue = NULL;
130109967Sdes	strncpy(fn, u->doc, sizeof(fn) - 2);
131109967Sdes	fn[sizeof(fn) - 2] = 0;
13290267Sdes	strcat(fn, "/");
13390267Sdes	p = strchr(fn, 0);
134109967Sdes	l = sizeof(fn) - strlen(fn) - 1;
13590267Sdes
13690267Sdes	while ((de = readdir(dir)) != NULL) {
13790267Sdes		strncpy(p, de->d_name, l - 1);
13890267Sdes		p[l - 1] = 0;
139174588Sdes		if (fetch_stat_file(fn, &us) == -1)
14090267Sdes			/* should I return a partial result, or abort? */
14190267Sdes			break;
142174588Sdes		fetch_add_entry(&ue, &size, &len, de->d_name, &us);
14390267Sdes	}
14490267Sdes
14590267Sdes	return (ue);
14641989Sdes}
147