fix compiler warning
[ladish.git] / daemon / studio_list.c
blob0d240485c548d9105237c9246501f404f2b92a54
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
7 **************************************************************************
8 * This file contains studio list implementation
9 **************************************************************************
11 * LADI Session Handler is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * LADI Session Handler is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
23 * or write to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "common.h"
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <dirent.h>
34 #include "studio_internal.h"
35 #include "../common/catdup.h"
36 #include "escape.h"
38 struct ladish_studios_iterate_context
40 void * call_ptr;
41 void * context;
42 bool (* callback)(void * call_ptr, void * context, const char * studio, uint32_t modtime);
43 unsigned int counter;
46 #define ctx_ptr ((struct ladish_studios_iterate_context *)callback_context)
48 bool recent_studio_callback(void * callback_context, const char * item)
50 char * path;
51 struct stat st;
53 if (!ladish_studio_compose_filename(item, &path, NULL))
55 log_error("failed to compose path of (recent) studio \%s\" file", item);
56 goto exit;
59 if (stat(path, &st) != 0)
61 if (errno != ENOENT)
63 log_error("failed to stat '%s': %d (%s)", path, errno, strerror(errno));
66 goto free;
69 if (!S_ISREG(st.st_mode))
71 log_info("Ignoring recent studio that is not regular file. Mode is %07o", st.st_mode);
72 goto free;
75 ctx_ptr->callback(ctx_ptr->call_ptr, ctx_ptr->context, item, st.st_mtime);
76 ctx_ptr->counter++;
78 free:
79 free(path);
80 exit:
81 return true;
84 #undef ctx_ptr
86 bool ladish_studios_iterate(void * call_ptr, void * context, bool (* callback)(void * call_ptr, void * context, const char * studio, uint32_t modtime))
88 DIR * dir;
89 struct dirent * dentry;
90 size_t len;
91 struct stat st;
92 char * path;
93 char * name;
94 struct ladish_studios_iterate_context ctx;
96 ctx.call_ptr = call_ptr;
97 ctx.context = context;
98 ctx.callback = callback;
99 ctx.counter = 0;
101 ladish_recent_store_iterate_items(g_studios_recent_store, &ctx, recent_studio_callback);
103 /* TODO: smarter error handling based on ctx.counter (dbus error vs just logged error) */
105 dir = opendir(g_studios_dir);
106 if (dir == NULL)
108 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "Cannot open directory '%s': %d (%s)", g_studios_dir, errno, strerror(errno));
109 return false;
112 while ((dentry = readdir(dir)) != NULL)
114 len = strlen(dentry->d_name);
115 if (len <= 4 || strcmp(dentry->d_name + (len - 4), ".xml") != 0)
116 continue;
118 path = catdup(g_studios_dir, dentry->d_name);
119 if (path == NULL)
121 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "catdup() failed");
122 return false;
125 if (stat(path, &st) != 0)
127 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "failed to stat '%s': %d (%s)", path, errno, strerror(errno));
128 free(path);
129 return false;
132 free(path);
134 if (!S_ISREG(st.st_mode))
136 //log_info("Ignoring direntry that is not regular file. Mode is %07o", st.st_mode);
137 continue;
140 name = malloc(len - 4 + 1);
141 if (name == NULL)
143 log_error("malloc() failed.");
144 closedir(dir);
145 return false;
148 name[unescape(dentry->d_name, len - 4, name)] = 0;
149 //log_info("name = '%s'", name);
151 if (!ladish_recent_store_check_known(g_studios_recent_store, name))
153 if (!callback(call_ptr, context, name, st.st_mtime))
155 free(name);
156 closedir(dir);
157 return false;
161 free(name);
164 closedir(dir);
165 return true;