summaryrefslogtreecommitdiff
path: root/rpmio/rpmglob.c
diff options
context:
space:
mode:
authorMichal Domonkos <mdomonko@redhat.com>2022-05-09 16:48:33 +0200
committerPanu Matilainen <pmatilai@redhat.com>2022-09-20 15:01:05 +0300
commit8ef29094fa218c631b3abadb2d90f3d36368ca76 (patch)
treef3aa167eae222814a6b29c335b3a73296cfcca31 /rpmio/rpmglob.c
parentaca8bf24bbb59cba080ae43a6564ce9e22f18e0e (diff)
downloadrpm-8ef29094fa218c631b3abadb2d90f3d36368ca76.tar.gz
Try globs literally when there are no matches
When a glob yields no matches, try accessing a file named like the literal pattern before finally giving up. Do this for any globs supplied by the user, be it on the CLI or through a %files section. We already do this with regular files in %files, this commit just extends the same logic to the remaining places, namely special files (%doc or %license) and package files passed on the CLI in install or query mode (either directly or indirectly through a manifest). This makes globbing in RPM consistent and more shell-like as Bash does the same by default. Do this by treating globs as filenames that may or may not expand into multiple ones. That way, both cases can be handled by the same code path. We don't need to check for the existence of the literal pattern since that's eventually taken care of in the rpmGlob() caller, such as in addFile(). As a nice side effect, error reporting for missing glob and non-glob filenames is now also unified, see the updated tests. Preserve the public signature of rpmGlob(), though, by adding a new, more general wrapper that also takes flags. The name is chosen to fit the pre-existing scheme of rpm*Path() functions in rpmfileutil.h.
Diffstat (limited to 'rpmio/rpmglob.c')
-rw-r--r--rpmio/rpmglob.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/rpmio/rpmglob.c b/rpmio/rpmglob.c
index 2ccee27b8..ca35fee09 100644
--- a/rpmio/rpmglob.c
+++ b/rpmio/rpmglob.c
@@ -51,7 +51,8 @@ static int ismagic(const char *pattern)
/* librpmio exported interfaces */
-int rpmGlob(const char * pattern, int * argcPtr, ARGV_t * argvPtr)
+int rpmGlobPath(const char * pattern, rpmglobFlags flags,
+ int * argcPtr, ARGV_t * argvPtr)
{
int argc = 0;
ARGV_t argv = NULL;
@@ -61,7 +62,7 @@ int rpmGlob(const char * pattern, int * argcPtr, ARGV_t * argvPtr)
size_t plen = strlen(path);
int dir_only = (plen > 0 && path[plen-1] == '/');
glob_t gl;
- int flags = 0;
+ int gflags = 0;
int i;
int rc = 0;
@@ -80,11 +81,13 @@ int rpmGlob(const char * pattern, int * argcPtr, ARGV_t * argvPtr)
goto exit;
}
- flags |= GLOB_BRACE;
+ gflags |= GLOB_BRACE;
if (home != NULL && strlen(home) > 0)
- flags |= GLOB_TILDE;
+ gflags |= GLOB_TILDE;
if (dir_only)
- flags |= GLOB_ONLYDIR;
+ gflags |= GLOB_ONLYDIR;
+ if (flags & RPMGLOB_NOCHECK)
+ gflags |= GLOB_NOCHECK;
#ifdef ENABLE_NLS
t = setlocale(LC_COLLATE, NULL);
@@ -100,12 +103,12 @@ int rpmGlob(const char * pattern, int * argcPtr, ARGV_t * argvPtr)
gl.gl_pathc = 0;
gl.gl_pathv = NULL;
- rc = glob(pattern, flags, NULL, &gl);
+ rc = glob(pattern, gflags, NULL, &gl);
if (rc)
goto exit;
for (i = 0; i < gl.gl_pathc; i++) {
- if (dir_only) {
+ if (dir_only && !(flags & RPMGLOB_NOCHECK)) {
struct stat sb;
if (lstat(gl.gl_pathv[i], &sb) || !S_ISDIR(sb.st_mode))
continue;
@@ -135,3 +138,8 @@ exit:
return rc;
}
+
+int rpmGlob(const char * pattern, int * argcPtr, ARGV_t * argvPtr)
+{
+ return rpmGlobPath(pattern, RPMGLOB_NONE, argcPtr, argvPtr);
+}