/*
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with the program; if not, see <http://www.gnu.org/licenses/>  
 *
 *
 * Authors:
 *		Michael Zucchi <notzed@ximian.com>
 *
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 *
 */

#include <config.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

/* This isn't as portable as, say, the stuff in GNU coreutils.  But I care not for OSF1. */
#ifdef HAVE_STATVFS
# ifdef HAVE_SYS_STATVFS_H
#  include <sys/statvfs.h>
# endif
#else
#ifdef HAVE_STATFS
# ifdef HAVE_SYS_PARAM_H
#  include <sys/param.h>	/* bsd interface */
# endif
# ifdef HAVE_SYS_MOUNT_H
#  include <sys/mount.h>
# endif
#endif
#endif

#include <errno.h>
#include <string.h>

#include <glib.h>
#include <glib/gstdio.h>

#include "e-fsutils.h"

/**
 * e_fsutils_usage:
 * @path:
 *
 * Calculate the amount of disk space used by a given path.
 *
 * Return value: The number of 1024 byte blocks used by the
 * filesystem.
 **/
long e_fsutils_usage(const char *inpath)
{
	GDir *dir;
	const char *d;
	long size = 0;
	GSList *paths;

	/* iterative, depth-first scan, because i can ... */
	paths = g_slist_prepend(NULL, g_strdup(inpath));

	while (paths) {
		char *path = paths->data;

		paths = g_slist_remove_link(paths, paths);

		dir = g_dir_open(path, 0, NULL);
		if (dir == NULL) {
			g_free(path);
			goto fail;
		}

		while ((d = g_dir_read_name(dir))) {
			char *full_path;
			struct stat st;

			full_path = g_build_filename(path, d, NULL);
			if (g_stat(full_path, &st) == -1) {
				g_free(full_path);
				g_dir_close(dir);
				g_free(path);
				goto fail;
			} else if (S_ISDIR(st.st_mode)) {
				paths = g_slist_prepend(paths, full_path);
				full_path = NULL;
			} else if (S_ISREG(st.st_mode)) {
				/* This is in 512 byte blocks.  st_blksize is page size on linux,
				   on *BSD it might be significant. */
#ifndef G_OS_WIN32
				size += st.st_blocks/2;
#endif
			}

			g_free(full_path);
		}

		g_dir_close(dir);
		g_free(path);
	}

	return size;

fail:
	g_slist_foreach(paths, (GFunc)g_free, NULL);
	g_slist_free(paths);

	return -1;
}

/**
 * e_fsutils_avail:
 * @path:
 *
 * Find the available disk space at the given path.
 *
 * Return value: -1 if it could not be determined, otherwise the
 * number of disk blocks, expressed as system-independent, 1024 byte
 * blocks.
 **/
long
e_fsutils_avail(const char *path)
{
#if defined(HAVE_STATVFS)
	struct statvfs stfs;

	if (statvfs(path, &stfs) == -1)
		return -1;

	/* Assumes that frsize === power of 2 */
	if (stfs.f_frsize >= 1024)
		return stfs.f_bavail * (stfs.f_frsize / 1024);
	else
		return stfs.f_bavail / (1024 / stfs.f_frsize);
#elif defined(HAVE_STATFS)
	struct statfs stfs;

	if (statfs(path, &stfs) == -1)
		return -1;

	/* For BSD this isn't clear, it may be dependent on f_bsize */
	return stfs.f_bavail / 2;
#else
	errno = ENOSYS;
	return -1;
#endif
}

e='branches/2014Q4'>branches/2014Q4</option>
<option value='branches/2015Q1'>branches/2015Q1</option>
<option value='branches/2015Q2'>branches/2015Q2</option>
<option value='branches/2015Q3'>branches/2015Q3</option>
<option value='branches/2015Q4'>branches/2015Q4</option>
<option value='branches/2016Q1'>branches/2016Q1</option>
<option value='branches/2016Q2'>branches/2016Q2</option>
<option value='branches/2016Q3'>branches/2016Q3</option>
<option value='branches/2016Q4'>branches/2016Q4</option>
<option value='branches/2017Q1'>branches/2017Q1</option>
<option value='branches/2017Q2'>branches/2017Q2</option>
<option value='branches/2017Q3'>branches/2017Q3</option>
<option value='branches/2017Q4'>branches/2017Q4</option>
<option value='branches/2018Q1'>branches/2018Q1</option>
<option value='branches/2018Q2'>branches/2018Q2</option>
<option value='branches/2018Q3'>branches/2018Q3</option>
<option value='branches/2018Q4'>branches/2018Q4</option>
<option value='branches/2019Q1'>branches/2019Q1</option>
<option value='branches/2019Q2'>branches/2019Q2</option>
<option value='branches/2019Q3'>branches/2019Q3</option>
<option value='branches/2019Q4'>branches/2019Q4</option>
<option value='branches/2020Q1'>branches/2020Q1</option>
<option value='branches/2020Q2'>branches/2020Q2</option>
<option value='branches/2020Q3'>branches/2020Q3</option>
<option value='branches/2020Q4'>branches/2020Q4</option>
<option value='branches/2021Q1'>branches/2021Q1</option>
<option value='branches/RELEASE_8_4_0'>branches/RELEASE_8_4_0</option>
<option value='branches/RELENG_2_1_0'>branches/RELENG_2_1_0</option>
<option value='branches/RELENG_2_2'>branches/RELENG_2_2</option>
<option value='branches/RELENG_9_1_0'>branches/RELENG_9_1_0</option>
<option value='branches/RELENG_9_2_0'>branches/RELENG_9_2_0</option>
<option value='dependabot/npm_and_yarn/devel/electron4/files/eslint-utils-1.4.3'>dependabot/npm_and_yarn/devel/electron4/files/eslint-utils-1.4.3</option>
<option value='dependabot/npm_and_yarn/devel/electron4/files/lodash-4.17.15'>dependabot/npm_and_yarn/devel/electron4/files/lodash-4.17.15</option>
<option value='dependabot/npm_and_yarn/devel/electron4/files/lodash.merge-4.6.2'>dependabot/npm_and_yarn/devel/electron4/files/lodash.merge-4.6.2</option>
<option value='dependabot/npm_and_yarn/devel/electron4/files/lodash.template-4.5.0'>dependabot/npm_and_yarn/devel/electron4/files/lodash.template-4.5.0</option>
<option value='dependabot/npm_and_yarn/devel/electron4/files/minimist-1.2.2'>dependabot/npm_and_yarn/devel/electron4/files/minimist-1.2.2</option>
<option value='dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2' selected='selected'>dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2</option>
<option value='main'>main</option>
<option value='master'>master</option>
<option value='svn_head'>svn_head</option>
</select> <input type='submit' value='switch'/></form></td></tr>
<tr><td class='sub'>FreeBSD Ports (https://github.com/freebsd/freebsd-ports)</td><td class='sub right'></td></tr></table>
<table class='tabs'><tr><td>
<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/about/?h=dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2'>about</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/?h=dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2'>summary</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/refs/?h=dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2&amp;id=4b177bd43d07e77e39c7bbf2b7f269be2ee6e2de'>refs</a><a class='active' href='/~lantw44/cgit/cgit.cgi/freebsd-ports/log/databases/p5-Oryx?h=dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2'>log</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/tree/databases/p5-Oryx?h=dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2&amp;id=4b177bd43d07e77e39c7bbf2b7f269be2ee6e2de'>tree</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/commit/databases/p5-Oryx?h=dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2&amp;id=4b177bd43d07e77e39c7bbf2b7f269be2ee6e2de'>commit</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/diff/databases/p5-Oryx?h=dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2&amp;id=4b177bd43d07e77e39c7bbf2b7f269be2ee6e2de'>diff</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/stats/databases/p5-Oryx?h=dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2'>stats</a></td><td class='form'><form class='right' method='get' action='/~lantw44/cgit/cgit.cgi/freebsd-ports/log/databases/p5-Oryx'>
<input type='hidden' name='h' value='dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2'/><input type='hidden' name='id' value='4b177bd43d07e77e39c7bbf2b7f269be2ee6e2de'/><select name='qt'>
<option value='grep'>log msg</option>
<option value='author'>author</option>
<option value='committer'>committer</option>
<option value='range'>range</option>
</select>
<input class='txt' type='search' size='10' name='q' value=''/>
<input type='submit' value='search'/>
</form>
</td></tr></table>
<div class='path'>path: <a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/log/?h=dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2&amp;id=4b177bd43d07e77e39c7bbf2b7f269be2ee6e2de'>root</a>/<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/log/databases?h=dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2&amp;id=4b177bd43d07e77e39c7bbf2b7f269be2ee6e2de'>databases</a>/<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/log/databases/p5-Oryx?h=dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2&amp;id=4b177bd43d07e77e39c7bbf2b7f269be2ee6e2de'>p5-Oryx</a></div><div class='content'><table class='list nowrap'><tr class='nohover'><th></th><th class='left'>Commit message (<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/log/databases/p5-Oryx?h=dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2&amp;id=4b177bd43d07e77e39c7bbf2b7f269be2ee6e2de&amp;showmsg=1'>Expand</a>)</th><th class='left'>Author</th><th class='left'>Age</th><th class='left'>Files</th><th class='left'>Lines</th></tr>