new functionality - file_get_properties()
[mediadatabase.git] / fuse / main.c
blob4e6a9f00d8f06b8234ee057fa0891f77691de6cd
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * DESCRIPTION:
5 * fuse frontend to MediaDatabase
7 * AUTHOR:
8 * Nedko Arnaudov <nedko@users.sourceforge.net>
10 * LICENSE:
11 * GNU GENERAL PUBLIC LICENSE version 2
13 *****************************************************************************/
15 #include <fuse.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <errno.h>
21 #include "../result.h"
22 #include "../libdb/libdb.h"
23 #include "../libfrontend/error.h"
24 #include "../libfrontend/conf.h"
25 #include "../libfrontend/db.h"
27 #define UNUSED_VARIABLE(x) ((void) (x))
29 mediadb_uint
30 mediadb_get_mediaid_from_path(
31 const char *path,
32 const char **ppMediaRoot)
34 const char * pch;
35 char * end;
36 mediadb_uint nMediaID;
38 if (path[0] != '/')
39 return 0;
41 pch = path + 1;
43 while (*pch != 0)
45 if (*pch == '/')
47 break;
50 pch++;
53 while (pch > path)
55 if (*pch == '#')
57 break;
60 pch--;
63 nMediaID = strtoull(pch+1, &end, 10);
64 if (nMediaID == 18446744073709551615ULL)
66 return 0;
69 if (*end != 0 && *end != '/')
71 return 0;
74 *ppMediaRoot = end;
75 return nMediaID;
78 static int mediadb_getattr(const char *path, struct stat *stbuf)
80 const char * pszMediaRoot;
81 mediadb_result r;
82 mediadb_uint nMediaID;
83 mediadb_uint nTotalFiles;
84 mediadb_uint nTotalSize;
85 mediadb_uint nTimeAdded;
86 mediadb_mediatype nType;
87 mediadb_uint nLocationID;
88 char *pszTitle;
89 mediadb_filetype Filetype;
90 mediadb_uint nSize;
91 mediadb_uint nTime;
92 char *pszPath, *pszName;
94 memset(stbuf, 0, sizeof(struct stat));
96 if (path[0] == '/' && path[1] == 0)
98 stbuf->st_mode = __S_IFDIR|0555;
99 return 0;
102 nMediaID = mediadb_get_mediaid_from_path(
103 path,
104 &pszMediaRoot);
105 if (nMediaID == 0)
107 return -EINVAL;
110 if (*pszMediaRoot == 0)
112 stbuf->st_mode = __S_IFDIR|0555;
113 r = mediadb_media_get_properties_data(
114 g_hDB,
115 nMediaID,
116 &nTotalFiles,
117 &nTotalSize);
118 if (MEDIADB_IS_SUCCESS(r))
120 stbuf->st_size = nTotalSize;
121 stbuf->st_nlink = nTotalFiles;
124 r = mediadb_media_get_properties(
125 g_hDB,
126 nMediaID,
127 &nTimeAdded,
128 &nType,
129 &nLocationID,
130 &pszTitle);
131 if (MEDIADB_IS_SUCCESS(r))
133 stbuf->st_ctime = nTimeAdded;
134 stbuf->st_atime = nTimeAdded;
135 stbuf->st_mtime = nTimeAdded;
136 free(pszTitle);
139 else
141 stbuf->st_mode = __S_IFREG;
143 pszPath = strdup(pszMediaRoot);
144 pszName = strrchr(pszPath, '/');
145 if (pszName == NULL)
147 return -EINVAL;
150 *pszName = 0;
151 pszName++;
153 r = mediadb_file_get_properties(
154 g_hDB,
155 nMediaID,
156 pszPath,
157 pszName,
158 &Filetype,
159 &nSize,
160 &nTime);
161 if (MEDIADB_IS_SUCCESS(r))
163 if (Filetype == MEDIADB_FILETYPE_FILE)
165 stbuf->st_mode = __S_IFREG|0444;
167 else if (Filetype == MEDIADB_FILETYPE_DIR)
169 stbuf->st_mode = __S_IFDIR|0444;
171 stbuf->st_size = nSize;
172 stbuf->st_ctime = nTime;
173 stbuf->st_atime = nTime;
174 stbuf->st_mtime = nTime;
177 free(pszPath);
180 return 0;
183 struct context_filldir
185 fuse_dirh_t h;
186 fuse_dirfil_t filler;
189 #define ctx ((struct context_filldir *)pUserContext)
191 void
192 mediadb_fuse_media_callback(
193 void *pUserContext,
194 mediadb_uint nMediaID,
195 mediadb_mediatype nType,
196 const char *pszName,
197 const char *pszComment,
198 mediadb_uint nTimeAdded,
199 mediadb_uint nTotalFiles,
200 mediadb_uint nTotalSize,
201 mediadb_uint nLocationID,
202 const char *pszLocation
205 size_t s;
206 char * entry, *pch;
208 s = strlen(pszName);
210 entry = (char *)malloc(s+100);
212 sprintf(entry, "%s #%u", pszName, (unsigned int)nMediaID);
214 for (pch = entry ; *pch != 0 ; pch++)
216 if (*pch == '/')
218 *pch = '|';
222 ctx->filler(ctx->h, entry, __S_IFREG, 0);
224 free(entry);
227 void
228 mediadb_fuse_files_callback(
229 void *pUserContext,
230 const char *pszPath,
231 const char *pszName,
232 mediadb_filetype Filetype,
233 mediadb_uint nSize,
234 mediadb_uint nTime)
236 if (Filetype == MEDIADB_FILETYPE_FILE)
238 ctx->filler(ctx->h, pszName, __S_IFREG, 0);
240 else if (Filetype == MEDIADB_FILETYPE_DIR)
242 ctx->filler(ctx->h, pszName, __S_IFDIR, 0);
246 #undef ctx
248 static int mediadb_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
250 int res = 0;
251 mediadb_result r;
252 struct context_filldir ctx;
253 mediadb_uint nMediaID;
254 const char * pszMediaRoot;
256 ctx.h = h;
257 ctx.filler = filler;
259 if (strcmp(path, "/") == 0)
261 r = mediadb_media_get_all(
262 g_hDB,
263 mediadb_fuse_media_callback,
264 &ctx);
266 else
268 nMediaID = mediadb_get_mediaid_from_path(
269 path,
270 &pszMediaRoot);
271 if (nMediaID == 0)
273 return -EINVAL;
276 r = mediadb_files_get(
277 g_hDB,
278 nMediaID,
279 pszMediaRoot,
280 mediadb_fuse_files_callback,
281 &ctx);
284 return res;
287 static struct fuse_operations mediadb_oper = {
288 .getattr = mediadb_getattr,
289 .getdir = mediadb_getdir,
292 int main(int argc, char *argv[])
294 mediadb_result r;
295 int ret;
297 /* Look into configuration file */
298 r = conf_parse();
300 db_set_defaults();
302 db_open();
304 ret = fuse_main(argc, argv, &mediadb_oper);
306 conf_cleanup();
308 db_uninit();
310 return ret;
313 void
314 mediadb_error_callback(
315 unsigned int nCritical,
316 const char *pszErrorDescription
319 fprintf(stderr,
320 "%s\n",
321 pszErrorDescription);
323 if (nCritical == MEDIADB_ERROR_CRITICAL)
325 exit(1);