X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=aft.c;h=fb0d4fd252b6091c2c7a3ae280d2746cc3519a36;hb=f3623744f5b28e0df91323cf5069f1932df7848d;hp=59be56eb68cd274debfe5077c5031687121fc7fa;hpb=780f2f681bccf82024bdb6da2e2cccaa0e084663;p=paraslash.git diff --git a/aft.c b/aft.c index 59be56eb..fb0d4fd2 100644 --- a/aft.c +++ b/aft.c @@ -293,60 +293,36 @@ static struct osl_table_description audio_file_table_desc = { .column_descriptions = aft_cols }; -/* We don't want dot or dot-dot anywhere. */ -static int verify_dotfile(const char *rest) -{ - /* - * The first character was '.', but that has already been discarded, we - * now test the rest. - */ - switch (*rest) { - case '\0': case '/': /* /foo/. and /foo/./bar are not ok */ - return -1; - case '.': /* path start with /foo/.. */ - if (rest[1] == '\0' || rest[1] == '/') - return -1; /* /foo/.. or /foo/../bar are not ok */ - /* /foo/..bar is ok */ - } - return 1; -} - /* - * We fundamentally don't like some paths: We don't want double slashes or - * slashes at the end that can make pathnames ambiguous. + * Produce a canonicalized absolute pathname. + * + * Returns one if the resolved path a directory, zero if it is a regular file, + * negative on errors. */ static int verify_path(const char *orig_path, char **resolved_path) { - char c; - size_t len; - char *path; + int ret; + char *path = NULL; + struct stat statbuf; if (*orig_path != '/') /* we only accept absolute paths */ - return -E_BAD_PATH; - len = strlen(orig_path); - *resolved_path = para_strdup(orig_path); - path = *resolved_path; - while (len > 1 && path[--len] == '/') - path[len] = '\0'; /* remove slash at the end */ - c = *path++; - while (c) { - if (c == '/') { - c = *path++; - switch (c) { - case '/': /* double slash */ - goto bad_path; - case '.': - if (verify_dotfile(path) < 0) - goto bad_path; - default: - continue; - } - } - c = *path++; - } - return 1; -bad_path: - free(*resolved_path); + goto fail; + path = realpath(orig_path, NULL); + if (!path) + goto fail; + if (stat(path, &statbuf) < 0) + goto fail; + if (S_ISREG(statbuf.st_mode)) + ret = 0; + else if (S_ISDIR(statbuf.st_mode)) + ret = 1; + else + goto fail; + *resolved_path = path; + return ret; +fail: + *resolved_path = NULL; + free(path); return -E_BAD_PATH; } @@ -1981,7 +1957,6 @@ int com_add(struct command_context *cc) { int i, ret; struct private_add_data pad = {.cc = cc, .flags = 0}; - struct stat statbuf; for (i = 1; i < cc->argc; i++) { const char *arg = cc->argv[i]; @@ -2020,20 +1995,10 @@ int com_add(struct command_context *cc) return ret; continue; } - ret = stat(path, &statbuf); - if (ret < 0) { - ret = send_sb_va(&cc->scc, SBD_ERROR_LOG, - "failed to stat %s (%s)\n", path, - strerror(errno)); - free(path); - if (ret < 0) - return ret; - continue; - } - if (S_ISDIR(statbuf.st_mode)) + if (ret == 1) /* directory */ ret = for_each_file_in_dir(path, add_one_audio_file, &pad); - else + else /* regular file */ ret = add_one_audio_file(path, &pad); if (ret < 0) { send_sb_va(&cc->scc, SBD_OUTPUT, "%s: %s\n", path,