137535Sdes/*-
2226537Sdes * 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
51289420Sdes	f = fopen(u->doc, "re");
5290267Sdes
53240495Seadler	if (f == NULL) {
54174588Sdes		fetch_syserr();
55240495Seadler		return (NULL);
56240495Seadler	}
5790267Sdes
5890267Sdes	if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) {
5990267Sdes		fclose(f);
60174588Sdes		fetch_syserr();
61240495Seadler		return (NULL);
6290267Sdes	}
6390267Sdes
6490267Sdes	return (f);
6537535Sdes}
6637535Sdes
6737535SdesFILE *
6875891SarchiefetchGetFile(struct url *u, const char *flags)
6963340Sdes{
7090267Sdes	return (fetchXGetFile(u, NULL, flags));
7163340Sdes}
7263340Sdes
7363340SdesFILE *
7475891SarchiefetchPutFile(struct url *u, const char *flags)
7537535Sdes{
7690267Sdes	FILE *f;
7790267Sdes
7890267Sdes	if (CHECK_FLAG('a'))
79289420Sdes		f = fopen(u->doc, "ae");
8090267Sdes	else
81289420Sdes		f = fopen(u->doc, "w+e");
8290267Sdes
83240495Seadler	if (f == NULL) {
84174588Sdes		fetch_syserr();
85240495Seadler		return (NULL);
86240495Seadler	}
8790267Sdes
8890267Sdes	if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) {
8990267Sdes		fclose(f);
90174588Sdes		fetch_syserr();
91240495Seadler		return (NULL);
9290267Sdes	}
9390267Sdes
9490267Sdes	return (f);
9537535Sdes}
9640975Sdes
9741989Sdesstatic int
98174588Sdesfetch_stat_file(const char *fn, struct url_stat *us)
9940975Sdes{
10090267Sdes	struct stat sb;
10140975Sdes
10290267Sdes	us->size = -1;
10390267Sdes	us->atime = us->mtime = 0;
10490267Sdes	if (stat(fn, &sb) == -1) {
105174588Sdes		fetch_syserr();
10690267Sdes		return (-1);
10790267Sdes	}
10890267Sdes	us->size = sb.st_size;
10990267Sdes	us->atime = sb.st_atime;
11090267Sdes	us->mtime = sb.st_mtime;
11190267Sdes	return (0);
11240975Sdes}
11341989Sdes
11441989Sdesint
11583076SdesfetchStatFile(struct url *u, struct url_stat *us, const char *flags __unused)
11641989Sdes{
117174588Sdes	return (fetch_stat_file(u->doc, us));
11841989Sdes}
11941989Sdes
12041989Sdesstruct url_ent *
12183076SdesfetchListFile(struct url *u, const char *flags __unused)
12241989Sdes{
12390267Sdes	struct dirent *de;
12490267Sdes	struct url_stat us;
12590267Sdes	struct url_ent *ue;
12690267Sdes	int size, len;
12790267Sdes	char fn[PATH_MAX], *p;
12890267Sdes	DIR *dir;
12990267Sdes	int l;
13041989Sdes
13190267Sdes	if ((dir = opendir(u->doc)) == NULL) {
132174588Sdes		fetch_syserr();
13390267Sdes		return (NULL);
13490267Sdes	}
13541989Sdes
13690267Sdes	ue = NULL;
137109967Sdes	strncpy(fn, u->doc, sizeof(fn) - 2);
138109967Sdes	fn[sizeof(fn) - 2] = 0;
13990267Sdes	strcat(fn, "/");
14090267Sdes	p = strchr(fn, 0);
141109967Sdes	l = sizeof(fn) - strlen(fn) - 1;
14290267Sdes
14390267Sdes	while ((de = readdir(dir)) != NULL) {
14490267Sdes		strncpy(p, de->d_name, l - 1);
14590267Sdes		p[l - 1] = 0;
146174588Sdes		if (fetch_stat_file(fn, &us) == -1)
14790267Sdes			/* should I return a partial result, or abort? */
14890267Sdes			break;
149174588Sdes		fetch_add_entry(&ue, &size, &len, de->d_name, &us);
15090267Sdes	}
15190267Sdes
152300666Struckman	closedir(dir);
15390267Sdes	return (ue);
15441989Sdes}
155