137535Sdes/*-
2236103Sdes * Copyright (c) 1998-2011 Dag-Erling 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$");
3184203Sdillon
3241862Sdes#include <sys/param.h>
3340975Sdes#include <sys/stat.h>
3441989Sdes
3541989Sdes#include <dirent.h>
36221830Sdes#include <fcntl.h>
3737535Sdes#include <stdio.h>
3837535Sdes#include <string.h>
3937535Sdes
4037535Sdes#include "fetch.h"
4140975Sdes#include "common.h"
4237535Sdes
4337535SdesFILE *
4475891SarchiefetchXGetFile(struct url *u, struct url_stat *us, const char *flags)
4537535Sdes{
4690267Sdes	FILE *f;
4760187Sdes
4890267Sdes	if (us && fetchStatFile(u, us, flags) == -1)
4990267Sdes		return (NULL);
5090267Sdes
5190267Sdes	f = fopen(u->doc, "r");
5290267Sdes
53241016Seadler	if (f == NULL) {
54174588Sdes		fetch_syserr();
55241016Seadler		return (NULL);
56241016Seadler	}
5790267Sdes
5890267Sdes	if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) {
5990267Sdes		fclose(f);
60174588Sdes		fetch_syserr();
61241016Seadler		return (NULL);
6290267Sdes	}
6390267Sdes
64221830Sdes	fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
6590267Sdes	return (f);
6637535Sdes}
6737535Sdes
6837535SdesFILE *
6975891SarchiefetchGetFile(struct url *u, const char *flags)
7063340Sdes{
7190267Sdes	return (fetchXGetFile(u, NULL, flags));
7263340Sdes}
7363340Sdes
7463340SdesFILE *
7575891SarchiefetchPutFile(struct url *u, const char *flags)
7637535Sdes{
7790267Sdes	FILE *f;
7890267Sdes
7990267Sdes	if (CHECK_FLAG('a'))
8090267Sdes		f = fopen(u->doc, "a");
8190267Sdes	else
8290267Sdes		f = fopen(u->doc, "w+");
8390267Sdes
84241016Seadler	if (f == NULL) {
85174588Sdes		fetch_syserr();
86241016Seadler		return (NULL);
87241016Seadler	}
8890267Sdes
8990267Sdes	if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) {
9090267Sdes		fclose(f);
91174588Sdes		fetch_syserr();
92241016Seadler		return (NULL);
9390267Sdes	}
9490267Sdes
95221830Sdes	fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
9690267Sdes	return (f);
9737535Sdes}
9840975Sdes
9941989Sdesstatic int
100174588Sdesfetch_stat_file(const char *fn, struct url_stat *us)
10140975Sdes{
10290267Sdes	struct stat sb;
10340975Sdes
10490267Sdes	us->size = -1;
10590267Sdes	us->atime = us->mtime = 0;
10690267Sdes	if (stat(fn, &sb) == -1) {
107174588Sdes		fetch_syserr();
10890267Sdes		return (-1);
10990267Sdes	}
11090267Sdes	us->size = sb.st_size;
11190267Sdes	us->atime = sb.st_atime;
11290267Sdes	us->mtime = sb.st_mtime;
11390267Sdes	return (0);
11440975Sdes}
11541989Sdes
11641989Sdesint
11783076SdesfetchStatFile(struct url *u, struct url_stat *us, const char *flags __unused)
11841989Sdes{
119174588Sdes	return (fetch_stat_file(u->doc, us));
12041989Sdes}
12141989Sdes
12241989Sdesstruct url_ent *
12383076SdesfetchListFile(struct url *u, const char *flags __unused)
12441989Sdes{
12590267Sdes	struct dirent *de;
12690267Sdes	struct url_stat us;
12790267Sdes	struct url_ent *ue;
12890267Sdes	int size, len;
12990267Sdes	char fn[PATH_MAX], *p;
13090267Sdes	DIR *dir;
13190267Sdes	int l;
13241989Sdes
13390267Sdes	if ((dir = opendir(u->doc)) == NULL) {
134174588Sdes		fetch_syserr();
13590267Sdes		return (NULL);
13690267Sdes	}
13741989Sdes
13890267Sdes	ue = NULL;
139109967Sdes	strncpy(fn, u->doc, sizeof(fn) - 2);
140109967Sdes	fn[sizeof(fn) - 2] = 0;
14190267Sdes	strcat(fn, "/");
14290267Sdes	p = strchr(fn, 0);
143109967Sdes	l = sizeof(fn) - strlen(fn) - 1;
14490267Sdes
14590267Sdes	while ((de = readdir(dir)) != NULL) {
14690267Sdes		strncpy(p, de->d_name, l - 1);
14790267Sdes		p[l - 1] = 0;
148174588Sdes		if (fetch_stat_file(fn, &us) == -1)
14990267Sdes			/* should I return a partial result, or abort? */
15090267Sdes			break;
151174588Sdes		fetch_add_entry(&ue, &size, &len, de->d_name, &us);
15290267Sdes	}
15390267Sdes
15490267Sdes	return (ue);
15541989Sdes}
156