#include <limits.h>
#include <sqlite3.h>
#include <errno.h>
+#include <sys/stat.h>
static int color = 0;
static const char short_options[] = "s:S:p:P::c:i:t:m:v::h";
static int
work(lms_t *lms, int method, int verbose, const char *path)
{
+ struct stat st;
int r;
if (verbose) {
return r;
}
+ if (stat(path, &st) != 0) {
+ printf("PROCESS skipped for '%s': doesn't exist.\n", path);
+ return 0;
+ }
if (verbose) {
lms_set_progress_callback(lms, progress, "PROGRESS", NULL);
int r, len;
if (!realpath(orig_path, path)) {
- fprintf(stderr, "ERROR: could not realpath(\"%s\"): %s\n",
- orig_path, strerror(errno));
- return -1;
+ len = strlen(orig_path);
+ if (len + 1 < PATH_MAX)
+ memcpy(path, orig_path, len + 1);
+ else {
+ fprintf(stderr, "ERROR: path is too long: %s\n", orig_path);
+ return -1;
+ }
}
len = strlen(path);
}
static int
+_is_file(const char *path)
+{
+ struct stat st;
+ if (stat(path, &st) != 0)
+ return 0;
+ return S_ISREG(st.st_mode);
+}
+
+static int
_check(struct pinfo *pinfo, int len, char *path)
{
- char query[PATH_SIZE + 2];
+ char query[PATH_SIZE + 3];
struct master_db *db;
int ret;
if (!db)
return -1;
- memcpy(query, path, len);
- query[len] = '%';
- query[len + 1] = '\0';
- ret = lms_db_get_files(db->get_files, query, len + 1);
+ if (_is_file(path))
+ memcpy(query, path, len + 1);
+ else {
+ memcpy(query, path, len);
+ memcpy(query + len, "/%", sizeof("/%"));
+ len += sizeof("/%") - 1;
+ }
+ ret = lms_db_get_files(db->get_files, query, len);
if (ret != 0)
goto end;
if (!db)
return -1;
- memcpy(query, path, len);
- query[len] = '%';
- query[len + 1] = '\0';
- ret = lms_db_get_files(db->get_files, query, len + 1);
+ if (_is_file(path))
+ memcpy(query, path, len + 1);
+ else {
+ memcpy(query, path, len);
+ memcpy(query + len, "/%", sizeof("/%"));
+ len += sizeof("/%") - 1;
+ }
+ ret = lms_db_get_files(db->get_files, query, len);
if (ret != 0)
goto end;
}
/**
- * Check consistency of given directory.
+ * Check consistency of given directory or file.
*
* This will update media in the given directory or its children. If files
* are missing, they'll be marked as deleted (dtime is set), if they were
* marked as deleted and are now present, they are unmarked (dtime is unset).
*
* @param lms previously allocated Light Media Scanner instance.
- * @param top_path top directory to scan.
+ * @param top_path top directory or file to scan.
*
* @return On success 0 is returned.
*/
}
if (realpath(top_path, path) == NULL) {
- perror("realpath");
- r = -6;
- goto close_pipes;
+ int len = strlen(top_path);
+ if (len + 1 < PATH_SIZE)
+ memcpy(path, top_path, len + 1);
+ else {
+ fprintf(stderr, "ERROR: path is too long: %s\n", top_path);
+ return -5;
+ }
}
lms->is_processing = 1;
lms->is_processing = 0;
lms->stop_processing = 0;
- close_pipes:
lms_close_pipes(&pinfo);
end:
return r;
}
/**
- * Check consistency of given directory *without fork()-ing* into child process.
+ * Check consistency of given directory or file *without fork()-ing* into child process.
*
* This will update media in the given directory or its children. If files
* are missing, they'll be marked as deleted (dtime is set), if they were
* Note that if a parser hangs in the check process, this call will also hang.
*
* @param lms previously allocated Light Media Scanner instance.
- * @param top_path top directory to scan.
+ * @param top_path top directory or file to scan.
*
* @return On success 0 is returned.
*/
sinfo.total_committed = 0;
if (realpath(top_path, path) == NULL) {
- perror("realpath");
- return -6;
+ int len = strlen(top_path);
+ if (len + 1 < PATH_SIZE)
+ memcpy(path, top_path, len + 1);
+ else {
+ fprintf(stderr, "ERROR: path is too long: %s\n", top_path);
+ return -5;
+ }
}
lms->is_processing = 1;
return -2;
}
- if (S_ISREG(st.st_mode))
- return process_file(info, base, path, name);
- else if (S_ISDIR(st.st_mode))
- return _process_dir(info, base, path, name, process_file);
- else {
+ if (S_ISREG(st.st_mode)) {
+ int r = process_file(info, base, path, name);
+ if (r >= 0) /* if success and ignore non-fatal errors */
+ return 0;
+ return r;
+ } else if (S_ISDIR(st.st_mode)) {
+ int r = _process_dir(info, base, path, name, process_file);
+ if (r >= 0) /* ignore non-fatal errors */
+ return 0;
+ return r;
+ } else {
fprintf(stderr,
"INFO: %s is neither a directory nor a regular file.\n", path);
return -3;
lms->is_processing = 1;
lms->stop_processing = 0;
- r = _process_dir(info, len, path, bname, process_file);
+ r = _process_unknown(info, len, path, bname, process_file);
lms->is_processing = 0;
lms->stop_processing = 0;
free(bname);
}
/**
- * Process the given directory.
+ * Process the given directory or file.
*
* This will add or update media found in the given directory or its children.
*
* @param lms previously allocated Light Media Scanner instance.
- * @param top_path top directory to scan.
+ * @param top_path top directory or file to scan.
*
* @return On success 0 is returned.
*/
}
/**
- * Process the given directory *without fork()-ing* into child process.
+ * Process the given directory or file *without fork()-ing* into child process.
*
* This will add or update media found in the given directory or its children.
* Note that if a parser hangs during the process, this call will also hang.
*
* @param lms previously allocated Light Media Scanner instance.
- * @param top_path top directory to scan.
+ * @param top_path top directory or file to scan.
*
* @return On success 0 is returned.
*/