<commit_before>/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */

#include "lib.h"
#include "str.h"
#include "mail-error.h"

#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>

bool mail_error_from_errno(enum mail_error *error_r,
			   const char **error_string_r)
{
	if (ENOACCESS(errno)) {
		*error_r = MAIL_ERROR_PERM;
		*error_string_r = MAIL_ERRSTR_NO_PERMISSION;
	} else if (ENOSPACE(errno)) {
		*error_r = MAIL_ERROR_NOSPACE;
		*error_string_r = MAIL_ERRSTR_NO_SPACE;
	} else if (ENOTFOUND(errno)) {
		*error_r = MAIL_ERROR_NOTFOUND;
		*error_string_r = errno != ELOOP ? "Not found" :
			"Directory structure is broken";
	} else {
		return FALSE;
	}
	return TRUE;
}

const char *mail_error_eacces_msg(const char *func, const char *path)
{
	const char *prev_path = path, *dir = "/", *p;
	const struct passwd *pw;
	const struct group *group;
	string_t *errmsg;
	struct stat st;
	int ret = -1;

	errmsg = t_str_new(256);
	str_printfa(errmsg, "%s(%s) failed: Permission denied (euid=%s",
		    func, path, dec2str(geteuid()));

	pw = getpwuid(geteuid());
	if (pw != NULL)
		str_printfa(errmsg, "(%s)", pw->pw_name);

	str_printfa(errmsg, " egid=%s", dec2str(getegid()));
	group = getgrgid(getegid());
	if (group != NULL)
		str_printfa(errmsg, "(%s)", group->gr_name);

	while ((p = strrchr(prev_path, '/')) != NULL) {
		dir = t_strdup_until(prev_path, p);
		ret = stat(dir, &st);
		if (ret == 0 || errno != EACCES)
			break;
		prev_path = dir;
		dir = "/";
	}

	if (ret == 0) {
		if (access(dir, X_OK) < 0 && errno == EACCES)
			str_printfa(errmsg, " missing +x perm: %s", dir);
		else if (prev_path == path &&
			 access(path, R_OK) < 0 && errno == EACCES)
			str_printfa(errmsg, " missing +r perm: %s", path);
		else
			str_printf(errmsg, " UNIX perms seem ok, ACL problem?");
	}
	str_append_c(errmsg, ')');
	return str_c(errmsg);
}<commit_msg>Fix to previous commit to actually compile..<commit_after>/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */

#include "lib.h"
#include "str.h"
#include "mail-error.h"

#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>

bool mail_error_from_errno(enum mail_error *error_r,
			   const char **error_string_r)
{
	if (ENOACCESS(errno)) {
		*error_r = MAIL_ERROR_PERM;
		*error_string_r = MAIL_ERRSTR_NO_PERMISSION;
	} else if (ENOSPACE(errno)) {
		*error_r = MAIL_ERROR_NOSPACE;
		*error_string_r = MAIL_ERRSTR_NO_SPACE;
	} else if (ENOTFOUND(errno)) {
		*error_r = MAIL_ERROR_NOTFOUND;
		*error_string_r = errno != ELOOP ? "Not found" :
			"Directory structure is broken";
	} else {
		return FALSE;
	}
	return TRUE;
}

const char *mail_error_eacces_msg(const char *func, const char *path)
{
	const char *prev_path = path, *dir = "/", *p;
	const struct passwd *pw;
	const struct group *group;
	string_t *errmsg;
	struct stat st;
	int ret = -1;

	errmsg = t_str_new(256);
	str_printfa(errmsg, "%s(%s) failed: Permission denied (euid=%s",
		    func, path, dec2str(geteuid()));

	pw = getpwuid(geteuid());
	if (pw != NULL)
		str_printfa(errmsg, "(%s)", pw->pw_name);

	str_printfa(errmsg, " egid=%s", dec2str(getegid()));
	group = getgrgid(getegid());
	if (group != NULL)
		str_printfa(errmsg, "(%s)", group->gr_name);

	while ((p = strrchr(prev_path, '/')) != NULL) {
		dir = t_strdup_until(prev_path, p);
		ret = stat(dir, &st);
		if (ret == 0 || errno != EACCES)
			break;
		prev_path = dir;
		dir = "/";
	}

	if (ret == 0) {
		if (access(dir, X_OK) < 0 && errno == EACCES)
			str_printfa(errmsg, " missing +x perm: %s", dir);
		else if (prev_path == path &&
			 access(path, R_OK) < 0 && errno == EACCES)
			str_printfa(errmsg, " missing +r perm: %s", path);
		else
			str_printfa(errmsg, " UNIX perms seem ok, ACL problem?");
	}
	str_append_c(errmsg, ')');
	return str_c(errmsg);
}
{'fraction_non_alphanumeric': 0.1664058424621805, 'fraction_numerical': 0.009389671361502348, 'mean_word_length': 4.260631001371742, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3600315', 'n_tokens_mistral': 1681, 'n_tokens_neox': 1567, 'n_words': 374}