return 1;
}
-static int verify_path(const char *path, char **resolved_path)
+static int verify_path(const char *orig_path, char **resolved_path)
{
- const char *orig_path = path;
char c;
const char prefix[] = AFS_AUDIO_FILE_DIR "/";
+ const char *path = orig_path;
const size_t prefix_len = strlen(prefix);
- PARA_DEBUG_LOG("path: %s\n", path);
c = *path++;
if (!c)
- return -E_BAD_PATH;
+ goto bad_path;
while (c) {
if (c == '/') {
c = *path++;
switch (c) {
default:
continue;
- case '/': case '\0':
- break;
+ case '/': /* double slash */
+ goto bad_path;
case '.':
- if (verify_dotfile(path) > 0)
- continue;
+ if (verify_dotfile(path) < 0)
+ goto bad_path;
}
- *resolved_path = NULL;
- return -E_BAD_PATH;
}
c = *path++;
}
- if (*orig_path == '/')
- *resolved_path = prefix_path("", 0, orig_path);
- else
+ if (*orig_path != '/')
*resolved_path = prefix_path(prefix, prefix_len, orig_path);
- PARA_DEBUG_LOG("resolved: %s\n", *resolved_path);
- return *resolved_path? 1: -E_BAD_PATH;
+ else
+ *resolved_path = para_strdup(orig_path);
+ return 1;
+bad_path:
+ return -E_BAD_PATH;
}
enum afhi_offsets {
}
/** The offsets of the data contained in the AFTCOL_CHUNKS column. */
-enum chunk_info_offsets {
+enum chunk_info_offsets{
/** The total number of chunks (4 bytes). */
CHUNKS_TOTAL_OFFSET = 0,
/** The length of the audio file header (4 bytes). */
{
struct osl_object obj = {.data = path, .size = strlen(path) + 1};
- PARA_NOTICE_LOG("audio_file_table: %p\n", audio_file_table);
return osl_get_row(audio_file_table, AFTCOL_PATH, &obj, row);
}
default_afsi.last_played = time(NULL) - 365 * 24 * 60 * 60;
default_afsi.audio_format_id = read_u8(buf + AFTROW_AUDIO_FORMAT_OFFSET);
- if (flags & ADD_FLAG_VERBOSE)
- PARA_NOTICE_LOG("adding %s\n", path);
objs[AFTCOL_AFSI].data = &afsi_buf;
objs[AFTCOL_AFSI].size = AFSI_SIZE;
save_afsi(&default_afsi, &objs[AFTCOL_AFSI]);
return 1;
}
-
static int add_one_audio_file(const char *arg, const void *private_data)
{
int ret;
const struct private_add_data *pad = private_data;
struct audio_format_info afhi, *afhi_ptr = NULL;
struct osl_row *pb = NULL, *hs = NULL; /* path brother/hash sister */
- struct osl_object map, obj, query, result;
- char *path;
+ struct osl_object map, obj = {.data = NULL}, query, result;
+ char *path = NULL;
HASH_TYPE hash[HASH_SIZE];
afhi.header_offset = 0;
afhi.header_len = 0;
ret = verify_path(arg, &path);
if (ret < 0)
- return ret;
+ goto out_free;
query.data = path;
query.size = strlen(path) + 1;
ret = send_callback_request(path_brother_callback, &query, &result);
format_num = ret;
afhi_ptr = &afhi;
}
+ if (pad->flags & ADD_FLAG_VERBOSE)
+ send_va_buffer(pad->fd, "adding %s\n", path);
munmap(map.data, map.size);
save_audio_file_info(hash, path, afhi_ptr, pad->flags, format_num, &obj);
/* Ask afs to consider this entry for adding. */
munmap(map.data, map.size);
out_free:
if (ret < 0)
- send_va_buffer(pad->fd, "failed to add %s (%s)\n", path,
- PARA_STRERROR(-ret));
+ send_va_buffer(pad->fd, "failed to add %s (%s)\n", path?
+ path : arg, PARA_STRERROR(-ret));
free(obj.data);
free(path);
if (afhi_ptr)
free(afhi_ptr->chunk_table);
- return ret;
+ return 1; /* it's not an error if not all files could be added */
}
int com_add(int fd, int argc, char * const * const argv)
struct private_add_data pad = {.fd = fd, .flags = 0};
struct stat statbuf;
- PARA_NOTICE_LOG("argv[1]: %s\n", argv[1]);
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (arg[0] != '-')
if (argc <= i)
return -E_AFT_SYNTAX;
for (; i < argc; i++) {
- ret = stat(argv[i], &statbuf);
+ char *path = para_strdup(argv[i]);
+ size_t len = strlen(path);
+ while (len > 1 && path[--len] == '/')
+ path[len] = '\0';
+ ret = stat(path, &statbuf);
if (ret < 0)
- return -E_AFS_STAT;
- if (S_ISDIR(statbuf.st_mode)) {
- ret = for_each_file_in_dir(argv[i],
- add_one_audio_file, &pad);
- continue;
- }
- ret = add_one_audio_file(argv[i], &pad);
+ PARA_NOTICE_LOG("failed to stat %s (%s)", path,
+ strerror(errno));
+ else
+ if (S_ISDIR(statbuf.st_mode))
+ for_each_file_in_dir(path, add_one_audio_file,
+ &pad);
+ else
+ add_one_audio_file(path, &pad);
+ free(path);
}
ret = 1;
return ret;