|
Packit |
8ea169 |
/*
|
|
Packit |
8ea169 |
Copyright (C) ABRT Team
|
|
Packit |
8ea169 |
Copyright (C) RedHat inc.
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
This program is free software; you can redistribute it and/or modify
|
|
Packit |
8ea169 |
it under the terms of the GNU General Public License as published by
|
|
Packit |
8ea169 |
the Free Software Foundation; either version 2 of the License, or
|
|
Packit |
8ea169 |
(at your option) any later version.
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
This program is distributed in the hope that it will be useful,
|
|
Packit |
8ea169 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
8ea169 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
8ea169 |
GNU General Public License for more details.
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
You should have received a copy of the GNU General Public License along
|
|
Packit |
8ea169 |
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
Packit |
8ea169 |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
#include <glib.h>
|
|
Packit |
8ea169 |
#include <sys/time.h>
|
|
Packit |
8ea169 |
#include "problem_api.h"
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/*
|
|
Packit |
8ea169 |
* Goes through all problems and for problems accessible by caller_uid
|
|
Packit |
8ea169 |
* calls callback. If callback returns non-0, returns that value.
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
int for_each_problem_in_dir(const char *path,
|
|
Packit |
8ea169 |
uid_t caller_uid,
|
|
Packit |
8ea169 |
int (*callback)(struct dump_dir *dd, void *arg),
|
|
Packit |
8ea169 |
void *arg)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
DIR *dp = opendir(path);
|
|
Packit |
8ea169 |
if (!dp)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
/* We don't want to yell if, say, $XDG_CACHE_DIR/abrt/spool doesn't exist */
|
|
Packit |
8ea169 |
//perror_msg("Can't open directory '%s'", path);
|
|
Packit |
8ea169 |
return 0;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
int brk = 0;
|
|
Packit |
8ea169 |
struct dirent *dent;
|
|
Packit |
8ea169 |
while ((dent = readdir(dp)) != NULL)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (dot_or_dotdot(dent->d_name))
|
|
Packit |
8ea169 |
continue; /* skip "." and ".." */
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
char *full_name = concat_path_file(path, dent->d_name);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
struct dump_dir *dd = dd_opendir(full_name, DD_OPEN_FD_ONLY
|
|
Packit |
8ea169 |
| DD_FAIL_QUIETLY_ENOENT
|
|
Packit |
8ea169 |
| DD_FAIL_QUIETLY_EACCES);
|
|
Packit |
8ea169 |
if (dd == NULL)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
VERB2 perror_msg("can't open problem directory '%s'", full_name);
|
|
Packit |
8ea169 |
free(full_name);
|
|
Packit |
8ea169 |
continue;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (caller_uid == -1 || dd_accessible_by_uid(dd, caller_uid))
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
/* Silently ignore *any* errors, not only EACCES.
|
|
Packit |
8ea169 |
* We saw "lock file is locked by process PID" error
|
|
Packit |
8ea169 |
* when we raced with wizard.
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
int sv_logmode = logmode;
|
|
Packit |
8ea169 |
/* Silently ignore errors only in the silent log level. */
|
|
Packit |
8ea169 |
logmode = g_verbose == 0 ? 0: sv_logmode;
|
|
Packit |
8ea169 |
dd = dd_fdopendir(dd, DD_OPEN_READONLY | DD_DONT_WAIT_FOR_LOCK);
|
|
Packit |
8ea169 |
logmode = sv_logmode;
|
|
Packit |
8ea169 |
if (dd)
|
|
Packit |
8ea169 |
brk = callback ? callback(dd, arg) : 0;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (dd)
|
|
Packit |
8ea169 |
dd_close(dd);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
free(full_name);
|
|
Packit |
8ea169 |
if (brk)
|
|
Packit |
8ea169 |
break;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
closedir(dp);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return brk;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* get_problem_dirs_for_uid and its helpers */
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static int add_dirname_to_GList(struct dump_dir *dd, void *arg)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (!dir_has_correct_permissions(dd->dd_dirname, DD_PERM_DAEMONS))
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_warning("Ignoring '%s': invalid owner, group or mode", dd->dd_dirname);
|
|
Packit |
8ea169 |
/*Do not break*/
|
|
Packit |
8ea169 |
return 0;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GList **list = arg;
|
|
Packit |
8ea169 |
*list = g_list_prepend(*list, xstrdup(dd->dd_dirname));
|
|
Packit |
8ea169 |
return 0;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GList *get_problem_dirs_for_uid(uid_t uid, const char *dump_location)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
GList *list = NULL;
|
|
Packit |
8ea169 |
for_each_problem_in_dir(dump_location, uid, add_dirname_to_GList, &list);
|
|
Packit |
8ea169 |
/*
|
|
Packit |
8ea169 |
* Why reverse?
|
|
Packit |
8ea169 |
* Because N*prepend+reverse is faster than N*append
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
return g_list_reverse(list);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* get_problem_dirs_not_accessible_by_uid and its helpers */
|
|
Packit |
8ea169 |
struct add_dirname_to_GList_if_not_accessible_args
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
uid_t uid;
|
|
Packit |
8ea169 |
GList *list;
|
|
Packit |
8ea169 |
};
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static int add_dirname_to_GList_if_not_accessible(struct dump_dir *dd, void *args)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
struct add_dirname_to_GList_if_not_accessible_args *param = (struct add_dirname_to_GList_if_not_accessible_args *)args;
|
|
Packit |
8ea169 |
/* Append if not accessible */
|
|
Packit |
8ea169 |
if (!dump_dir_accessible_by_uid(dd->dd_dirname, param->uid))
|
|
Packit |
8ea169 |
param->list = g_list_prepend(param->list, xstrdup(dd->dd_dirname));
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return 0;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GList *get_problem_dirs_not_accessible_by_uid(uid_t uid, const char *dump_location)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
struct add_dirname_to_GList_if_not_accessible_args args = {
|
|
Packit |
8ea169 |
.uid = uid,
|
|
Packit |
8ea169 |
.list = NULL,
|
|
Packit |
8ea169 |
};
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
for_each_problem_in_dir(dump_location, /*disable default uid check*/-1, add_dirname_to_GList_if_not_accessible, &args);
|
|
Packit |
8ea169 |
return g_list_reverse(args.list);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* get_problem_storages */
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GList *get_problem_storages(void)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
GList *paths = NULL;
|
|
Packit |
8ea169 |
load_abrt_conf();
|
|
Packit |
8ea169 |
paths = g_list_append(paths, xstrdup(g_settings_dump_location));
|
|
Packit |
8ea169 |
free_abrt_conf_data();
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return paths;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
int problem_dump_dir_is_complete(struct dump_dir *dd)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
return dd_exist(dd, FILENAME_COUNT);
|
|
Packit |
8ea169 |
}
|