Example #1
0
static int
my_g_metadata_store(const char *name, u_char *md, size_t size)
{
	char path[MAXPATHLEN];
	unsigned sectorsize;
	off_t mediasize;
	u_char *sector;
	int error, fd;

	pathgen(name, path, sizeof(path));
	sector = NULL;
	error = 0;

	fd = open(path, O_RDWR);
	if (fd == -1)
		return (errno);
	mediasize = g_get_mediasize(name);
	if (mediasize == 0) {
		error = errno;
		goto out;
	}
	sectorsize = g_get_sectorsize(name);
	if (sectorsize == 0) {
		error = errno;
		goto out;
	}
	assert(sectorsize >= size);
	sector = malloc(sectorsize);
	if (sector == NULL) {
		error = ENOMEM;
		goto out;
	}
	bcopy(md, sector, size);
	if (pwrite(fd, sector, sectorsize, mediasize - sectorsize) !=
	    (ssize_t)sectorsize) {
		error = errno;
		goto out;
	}
out:
	if (sector != NULL)
		free(sector);
	close(fd);
	return (error);
}
Example #2
0
int
main(void)
{
	int		 i;
	char		 buf[PATH_MAX];
	DIR		*cwd;
	struct req	 req;
	char		*p, *path, *subpath;

	/* Scan our run-time environment. */

	if (NULL == (cache = getenv("CACHE_DIR")))
		cache = "/cache/man.cgi";

	if (NULL == (progname = getenv("SCRIPT_NAME")))
		progname = "";

	if (NULL == (css = getenv("CSS_DIR")))
		css = "";

	if (NULL == (host = getenv("HTTP_HOST")))
		host = "localhost";

	/*
	 * First we change directory into the cache directory so that
	 * subsequent scanning for manpath directories is rooted
	 * relative to the same position.
	 */

	if (-1 == chdir(cache)) {
		perror(cache);
		resp_bad();
		return(EXIT_FAILURE);
	} else if (NULL == (cwd = opendir(cache))) {
		perror(cache);
		resp_bad();
		return(EXIT_FAILURE);
	} 

	memset(&req, 0, sizeof(struct req));

	strlcpy(buf, ".", PATH_MAX);
	pathgen(cwd, buf, &req);
	closedir(cwd);

	/* Next parse out the query string. */

	if (NULL != (p = getenv("QUERY_STRING")))
		http_parse(&req, p);

	/*
	 * Now juggle paths to extract information.
	 * We want to extract our filetype (the file suffix), the
	 * initial path component, then the trailing component(s).
	 * Start with leading subpath component. 
	 */

	subpath = path = NULL;
	req.page = PAGE__MAX;

	if (NULL == (path = getenv("PATH_INFO")) || '\0' == *path)
		req.page = PAGE_INDEX;

	if (NULL != path && '/' == *path && '\0' == *++path)
		req.page = PAGE_INDEX;

	/* Strip file suffix. */

	if (NULL != path && NULL != (p = strrchr(path, '.')))
		if (NULL != p && NULL == strchr(p, '/'))
			*p++ = '\0';

	/* Resolve subpath component. */

	if (NULL != path && NULL != (subpath = strchr(path, '/')))
		*subpath++ = '\0';

	/* Map path into one we recognise. */

	if (NULL != path && '\0' != *path)
		for (i = 0; i < (int)PAGE__MAX; i++) 
			if (0 == strcmp(pages[i], path)) {
				req.page = (enum page)i;
				break;
			}

	/* Route pages. */

	switch (req.page) {
	case (PAGE_INDEX):
		pg_index(&req, subpath);
		break;
	case (PAGE_SEARCH):
		pg_search(&req, subpath);
		break;
	case (PAGE_SHOW):
		pg_show(&req, subpath);
		break;
	default:
		resp_error404(path);
		break;
	}

	for (i = 0; i < (int)req.psz; i++) {
		free(req.p[i].path);
		free(req.p[i].name);
	}

	free(req.p);
	return(EXIT_SUCCESS);
}
Example #3
0
int
main(void)
{
	struct req	 req;
	struct itimerval itimer;
	const char	*path;
	const char	*querystring;
	int		 i;

	/* Poor man's ReDoS mitigation. */

	itimer.it_value.tv_sec = 2;
	itimer.it_value.tv_usec = 0;
	itimer.it_interval.tv_sec = 2;
	itimer.it_interval.tv_usec = 0;
	if (setitimer(ITIMER_VIRTUAL, &itimer, NULL) == -1) {
		fprintf(stderr, "setitimer: %s\n", strerror(errno));
		pg_error_internal();
		return(EXIT_FAILURE);
	}

	/* Scan our run-time environment. */

	if (NULL == (scriptname = getenv("SCRIPT_NAME")))
		scriptname = "";

	if ( ! validate_urifrag(scriptname)) {
		fprintf(stderr, "unsafe SCRIPT_NAME \"%s\"\n",
		    scriptname);
		pg_error_internal();
		return(EXIT_FAILURE);
	}

	/*
	 * First we change directory into the MAN_DIR so that
	 * subsequent scanning for manpath directories is rooted
	 * relative to the same position.
	 */

	if (-1 == chdir(MAN_DIR)) {
		fprintf(stderr, "MAN_DIR: %s: %s\n",
		    MAN_DIR, strerror(errno));
		pg_error_internal();
		return(EXIT_FAILURE);
	} 

	memset(&req, 0, sizeof(struct req));
	pathgen(&req);

	/* Next parse out the query string. */

	if (NULL != (querystring = getenv("QUERY_STRING")))
		http_parse(&req, querystring);

	if (req.q.manpath == NULL)
		req.q.manpath = mandoc_strdup(req.p[0]);
	else if ( ! validate_manpath(&req, req.q.manpath)) {
		pg_error_badrequest(
		    "You specified an invalid manpath.");
		return(EXIT_FAILURE);
	}

	if ( ! (NULL == req.q.arch || validate_urifrag(req.q.arch))) {
		pg_error_badrequest(
		    "You specified an invalid architecture.");
		return(EXIT_FAILURE);
	}

	/* Dispatch to the three different pages. */

	path = getenv("PATH_INFO");
	if (NULL == path)
		path = "";
	else if ('/' == *path)
		path++;

	if ('\0' != *path)
		pg_show(&req, path);
	else if (NULL != req.q.query)
		pg_search(&req);
	else
		pg_index(&req);

	free(req.q.manpath);
	free(req.q.arch);
	free(req.q.sec);
	free(req.q.query);
	for (i = 0; i < (int)req.psz; i++)
		free(req.p[i]);
	free(req.p);
	return(EXIT_SUCCESS);
}
Example #4
0
/*
 * Scan for indexable paths.
 * This adds all paths with "etc/catman.conf" to the buffer.
 */
static void
pathgen(DIR *dir, char *path, struct req *req)
{
	struct dirent	*d;
	char		*cp;
	DIR		*cd;
	int		 rc;
	size_t		 sz, ssz;

	sz = strlcat(path, "/", PATH_MAX);
	if (sz >= PATH_MAX) {
		fprintf(stderr, "%s: Path too long", path);
		return;
	} 

	/* 
	 * First, scan for the "etc" directory.
	 * If it's found, then see if it should cause us to stop.  This
	 * happens when a catman.conf is found in the directory.
	 */

	rc = 0;
	while (0 == rc && NULL != (d = readdir(dir))) {
		if (DT_DIR != d->d_type || strcmp(d->d_name, "etc"))
			continue;

		path[(int)sz] = '\0';
		ssz = strlcat(path, d->d_name, PATH_MAX);

		if (ssz >= PATH_MAX) {
			fprintf(stderr, "%s: Path too long", path);
			return;
		} else if (NULL == (cd = opendir(path))) {
			perror(path);
			return;
		} 
		
		rc = pathstop(cd);
		closedir(cd);
	}

	if (rc > 0) {
		/* This also strips the trailing slash. */
		path[(int)--sz] = '\0';
		req->p = mandoc_realloc
			(req->p, 
			 (req->psz + 1) * sizeof(struct paths));
		/*
		 * Strip out the leading "./" unless we're just a ".",
		 * in which case use an empty string as our name.
		 */
		req->p[(int)req->psz].path = mandoc_strdup(path);
		req->p[(int)req->psz].name = 
			cp = mandoc_strdup(path + (1 == sz ? 1 : 2));
		req->psz++;
		/* 
		 * The name is just the path with all the slashes taken
		 * out of it.  Simple but effective. 
		 */
		for ( ; '\0' != *cp; cp++) 
			if ('/' == *cp)
				*cp = ' ';
		return;
	} 

	/*
	 * If no etc/catman.conf was found, recursively enter child
	 * directory and continue scanning.
	 */

	rewinddir(dir);
	while (NULL != (d = readdir(dir))) {
		if (DT_DIR != d->d_type || '.' == d->d_name[0])
			continue;

		path[(int)sz] = '\0';
		ssz = strlcat(path, d->d_name, PATH_MAX);

		if (ssz >= PATH_MAX) {
			fprintf(stderr, "%s: Path too long", path);
			return;
		} else if (NULL == (cd = opendir(path))) {
			perror(path);
			return;
		}

		pathgen(cd, path, req);
		closedir(cd);
	}
}