1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * $Id: disk.c,v 1.2 2004/05/21 23:42:49 nedko Exp $
7 * Mediadatabase disk handling.
10 * Nedko Arnaudov <nedko@users.sourceforge.net>
13 * GNU GENERAL PUBLIC LICENSE version 2
15 *****************************************************************************/
24 #include "../result.h"
25 #include "../libdb/libdb.h"
28 #include "../libdb/memory.h"
31 #define DEFAULT_MOUNT_CMD "sudo /sbin/mount /cdrom"
32 #define DEFAULT_UNMOUNT_CMD "sudo /sbin/umount /cdrom"
34 #define DEFAULT_MOUNT_CMD "/bin/mount /cdrom"
35 #define DEFAULT_UNMOUNT_CMD "/bin/umount /cdrom"
37 #define DEFAULT_MOUNTDIR "/cdrom"
38 #define MAX_PATH_DEPTH 65535
40 char *g_pszDiskPath
= NULL
;
41 int g_blnMediaMounted
= 0;
42 char *g_pszMountCommand
= NULL
;
43 char *g_pszUnmountCommand
= NULL
;
47 disk_scan_callback pCallback
;
50 size_t nPathBufferSize
;
51 size_t nDiskPathPrefixLength
;
52 unsigned long nTotalFiles
;
53 unsigned long long nTotalSize
;
57 disk_set_path(const char *pszDiskPath
)
59 if (g_pszDiskPath
!= NULL
)
64 g_pszDiskPath
= strdup(pszDiskPath
);
66 if (g_pszDiskPath
== NULL
)
68 mediadb_error_callback(
69 MEDIADB_ERROR_CRITICAL
,
84 disk_set_mount_command(const char *pszMountCommand
)
86 if (g_pszMountCommand
!= NULL
)
88 free(g_pszMountCommand
);
91 g_pszMountCommand
= strdup(pszMountCommand
);
93 if (g_pszMountCommand
== NULL
)
95 mediadb_error_callback(
96 MEDIADB_ERROR_CRITICAL
,
105 disk_get_mount_command()
107 return g_pszMountCommand
;
111 disk_set_unmount_command(const char *pszUnmountCommand
)
113 if (g_pszUnmountCommand
!= NULL
)
115 free(g_pszUnmountCommand
);
118 g_pszUnmountCommand
= strdup(pszUnmountCommand
);
120 if (g_pszUnmountCommand
== NULL
)
122 mediadb_error_callback(
123 MEDIADB_ERROR_CRITICAL
,
132 disk_get_unmount_command()
134 return g_pszUnmountCommand
;
140 if (g_pszMountCommand
== NULL
)
142 g_pszMountCommand
= strdup(DEFAULT_MOUNT_CMD
);
143 if (g_pszMountCommand
== NULL
)
145 mediadb_error_callback(
146 MEDIADB_ERROR_CRITICAL
,
152 if (g_pszUnmountCommand
== NULL
)
154 g_pszUnmountCommand
= strdup(DEFAULT_UNMOUNT_CMD
);
155 if (g_pszUnmountCommand
== NULL
)
157 mediadb_error_callback(
158 MEDIADB_ERROR_CRITICAL
,
164 if (g_pszDiskPath
== NULL
)
166 g_pszDiskPath
= strdup(DEFAULT_MOUNTDIR
);
167 if (g_pszDiskPath
== NULL
)
169 mediadb_error_callback(
170 MEDIADB_ERROR_CRITICAL
,
181 ScanDir(struct scan_context
*pContext
, unsigned long nDepth
)
185 size_t nCurrentPathLength
;
190 if (nDepth
>= MAX_PATH_DEPTH
)
192 mediadb_error_printf(
193 MEDIADB_ERROR_NONCRITICAL
,
194 "Max path depth of \"%u\" reached.\n",
195 (unsigned int)MAX_PATH_DEPTH
);
200 nCurrentPathLength
= strlen(pContext
->pszPathBuffer
);
202 pDir
= opendir(pContext
->pszPathBuffer
);
205 mediadb_error_printf(
206 MEDIADB_ERROR_NONCRITICAL
,
207 "Cannot open \"%s\"",
208 pContext
->pszPathBuffer
);
213 while ((pDE
= readdir(pDir
)) != NULL
)
215 if (strcmp(pDE
->d_name
, ".") == 0)
218 if (strcmp(pDE
->d_name
, "..") == 0)
222 sizeName
= pDE
->d_namlen
;
224 sizeName
= strlen(pDE
->d_name
);
227 r
= maybe_enlarge_buffer(
228 &pContext
->pszPathBuffer
,
229 &pContext
->nPathBufferSize
,
230 nCurrentPathLength
+ sizeName
+ 1);
231 if (MEDIADB_IS_ERROR(r
))
233 mediadb_error_callback(
234 MEDIADB_ERROR_CRITICAL
,
239 memcpy(pContext
->pszPathBuffer
+ nCurrentPathLength
, pDE
->d_name
, sizeName
);
240 pContext
->pszPathBuffer
[nCurrentPathLength
+ sizeName
] = 0;
242 if (lstat(pContext
->pszPathBuffer
, &st
) != 0)
244 mediadb_error_printf(
245 MEDIADB_ERROR_NONCRITICAL
,
246 "Cannot stat() %s. Error is %d (%s)",
247 pContext
->pszPathBuffer
,
254 pContext
->pszPathBuffer
[nCurrentPathLength
] = 0;
256 r
= pContext
->pCallback(
257 pContext
->pUserContext
,
259 (S_ISDIR(st
.st_mode
))?MEDIADB_FILETYPE_DIR
:MEDIADB_FILETYPE_FILE
,
260 pContext
->pszPathBuffer
+ pContext
->nDiskPathPrefixLength
,
261 ((S_ISDIR(st
.st_mode
))?0:st
.st_size
),
263 if (MEDIADB_IS_ERROR(r
))
268 pContext
->nTotalFiles
++;
270 if (S_ISDIR(st
.st_mode
))
272 memcpy(pContext
->pszPathBuffer
+ nCurrentPathLength
, pDE
->d_name
, sizeName
);
273 memcpy(pContext
->pszPathBuffer
+ nCurrentPathLength
+ sizeName
, "/", 2);
274 r
= ScanDir(pContext
, nDepth
+ 1);
275 if (MEDIADB_IS_ERROR(r
))
282 pContext
->nTotalSize
+= st
.st_size
;
294 disk_scan(disk_scan_callback pCallback
,
296 mediadb_uint
*pnTotalFiles
,
297 mediadb_uint
*pnTotalSize
)
300 struct scan_context context
;
302 context
.pCallback
= pCallback
;
303 context
.pUserContext
= pUserContext
;
304 context
.pszPathBuffer
= NULL
;
305 context
.nPathBufferSize
= 0;
306 context
.nTotalFiles
= 0;
307 context
.nTotalSize
= 0;
309 context
.nDiskPathPrefixLength
= strlen(g_pszDiskPath
);
311 r
= maybe_enlarge_buffer(
312 &context
.pszPathBuffer
,
313 &context
.nPathBufferSize
,
314 context
.nDiskPathPrefixLength
+ 2);
315 if (MEDIADB_IS_ERROR(r
))
317 mediadb_error_callback(
318 MEDIADB_ERROR_CRITICAL
,
323 memcpy(context
.pszPathBuffer
, g_pszDiskPath
, context
.nDiskPathPrefixLength
);
324 memcpy(context
.pszPathBuffer
+ context
.nDiskPathPrefixLength
, "/", 2);
326 r
= ScanDir(&context
, 0);
328 if (MEDIADB_IS_SUCCESS(r
))
330 *pnTotalFiles
= context
.nTotalFiles
;
331 *pnTotalSize
= context
.nTotalSize
;
337 static mediadb_result
338 ExecuteCommand(const char *pszCommand
)
342 nRet
= system(pszCommand
);
345 mediadb_error_printf(
346 MEDIADB_ERROR_NONCRITICAL
,
347 "Cannot execute command \"%s\". "
348 "system() returned -1, error is %d (%s)\n",
357 if (WEXITSTATUS(nRet
) != 0)
359 mediadb_error_printf(
360 MEDIADB_ERROR_NONCRITICAL
,
361 "Cannot execute command \"%s\". "
362 "Command returned %d\n",
364 (int)WEXITSTATUS(nRet
));
368 else if (WIFSIGNALED(nRet
))
370 mediadb_error_printf(
371 MEDIADB_ERROR_NONCRITICAL
,
372 "Cannot execute command \"%s\". "
373 "Cammand was terminated because of signal %d\n",
375 (int)WTERMSIG(nRet
));
380 mediadb_error_printf(
381 MEDIADB_ERROR_NONCRITICAL
,
382 "Cannot execute command \"%s\". "
383 "system() returned %d\n",
397 r
= ExecuteCommand(g_pszMountCommand
);
398 if (MEDIADB_IS_SUCCESS(r
))
400 g_blnMediaMounted
= 1;
411 r
= ExecuteCommand(g_pszUnmountCommand
);
412 if (MEDIADB_IS_SUCCESS(r
))
414 g_blnMediaMounted
= 0;
423 if (g_blnMediaMounted
)
428 if (g_pszMountCommand
!= NULL
)
429 free(g_pszMountCommand
);
431 if (g_pszUnmountCommand
!= NULL
)
432 free(g_pszUnmountCommand
);
434 if (g_pszDiskPath
!= NULL
)
438 /*****************************************************************************
442 * !!! WARNING !!! Following lines are automatically updated by the CVS system.
445 * Revision 1.2 2004/05/21 23:42:49 nedko
446 * mediadb_error_callback() now tells if error is critical.
448 * Revision 1.1 2004/05/16 19:01:17 nedko
449 * libfrontend holds code common to frontends but not in libdb.
451 *****************************************************************************/