Skip to content

Commit dbedb24

Browse files
committed
Move ~/.rpmmacros and ~/.rpmrc to ~/.config/rpm/
The XDG cofiguration directory is the new default location for the macros and rpmrc file. Migrate legacy files automatically. Create symlinks from the home directory for compatibility with older rpm versions. Resolves: #3467
1 parent 74065ae commit dbedb24

File tree

2 files changed

+145
-4
lines changed

2 files changed

+145
-4
lines changed

lib/rpmrc.cc

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <string>
66
#include <unordered_map>
77
#include <vector>
8+
#include <filesystem>
89

910
#include <fcntl.h>
1011
#include <stdarg.h>
@@ -48,6 +49,8 @@
4849
using wrlock = std::unique_lock<std::shared_mutex>;
4950
using rdlock = std::shared_lock<std::shared_mutex>;
5051

52+
namespace fs = std::filesystem;
53+
5154
static const char * defrcfiles = NULL;
5255
const char * macrofiles = NULL;
5356

@@ -358,6 +361,83 @@ const char * lookupInDefaultTable(const char * name,
358361
return name;
359362
}
360363

364+
static void moveConfigFiles(std::string userdir)
365+
{
366+
fs::path home = std::getenv("HOME");
367+
std::error_code ec;
368+
std::error_code ec2;
369+
fs::path oldmacros = home / ".rpmmacros";
370+
fs::path oldrpmrc = home / ".rpmrc";
371+
fs::path macros_target = "";
372+
fs::path rpmrc_target = "";
373+
374+
if (userdir.substr(0, 2) == "~/")
375+
userdir.replace(0, 1, home);
376+
377+
fs::path userdir_path = userdir;
378+
fs::path newmacros = userdir_path / "macros";
379+
fs::path newrpmrc = userdir_path / "rpmrc";
380+
381+
if (!fs::is_regular_file(oldmacros) && !fs::is_regular_file(oldrpmrc))
382+
return;
383+
384+
fs::create_directories(userdir_path, ec);
385+
if (ec) goto err;
386+
387+
if (fs::is_regular_file(oldmacros)) {
388+
fs::copy(oldmacros, newmacros, ec);
389+
if (ec) goto err;
390+
macros_target = fs::relative(newmacros, home, ec);
391+
if (ec) goto err;
392+
}
393+
if (fs::is_regular_file(oldrpmrc)) {
394+
fs::copy(oldrpmrc, newrpmrc, ec);
395+
if (ec) goto err;
396+
rpmrc_target = fs::relative(newrpmrc, home, ec);
397+
if (ec) goto err;
398+
}
399+
400+
if (fs::is_regular_file(oldmacros)) {
401+
fs::remove(oldmacros, ec);
402+
if (ec) goto undo_remove;
403+
fs::create_symlink(macros_target , oldmacros, ec);
404+
if (ec) goto undo_remove;
405+
}
406+
if (fs::is_regular_file(oldrpmrc)) {
407+
fs::remove(oldrpmrc, ec);
408+
if (ec) goto undo_remove;
409+
fs::create_symlink(rpmrc_target , oldrpmrc, ec);
410+
if (ec) goto undo_remove;
411+
}
412+
413+
if (fs::is_symlink(oldmacros))
414+
rpmlog(RPMLOG_WARNING, "Migrated %s to %s (leaving a symlink)\n",
415+
oldmacros.c_str(), newmacros.c_str());
416+
if (fs::is_symlink(oldrpmrc))
417+
rpmlog(RPMLOG_WARNING, "Migrated %s to %s (leaving a symlink)\n",
418+
oldrpmrc.c_str(), newrpmrc.c_str());
419+
return;
420+
undo_remove:
421+
if (fs::is_symlink(oldmacros))
422+
fs::remove(oldmacros, ec2);
423+
if (fs::is_symlink(oldrpmrc))
424+
fs::remove(oldrpmrc, ec2);
425+
426+
if (fs::is_regular_file(newmacros))
427+
fs::copy(oldmacros, newmacros, ec2);
428+
if (fs::is_regular_file(newrpmrc))
429+
fs::copy(oldrpmrc, newrpmrc, ec2);
430+
err:
431+
/* userdir_path did not exist at the beginning */
432+
fs::remove_all(userdir_path, ec2);
433+
if (fs::exists(oldmacros))
434+
rpmlog(RPMLOG_ERR, "Could not migrate %s to %s: %s\n",
435+
oldmacros.c_str(), newmacros.c_str(), ec.message().c_str());
436+
if (fs::exists(oldrpmrc))
437+
rpmlog(RPMLOG_ERR, "Could not migrate %s to %s: %s\n",
438+
oldrpmrc.c_str(), newrpmrc.c_str(), ec.message().c_str());
439+
}
440+
361441
static void setDefaults(void)
362442
{
363443
/* If either is missing, we need to go through this whole dance */
@@ -380,6 +460,9 @@ static void setDefaults(void)
380460
const char *oldmacros = "~/.rpmmacros";
381461
const char *oldrc = "~/.rpmrc";
382462
if (rpmGlob(oldmacros, NULL, NULL) == 0 || rpmGlob(oldrc, NULL, NULL) == 0) {
463+
464+
moveConfigFiles(userdir);
465+
383466
free(usermacros);
384467
free(userrc);
385468
usermacros = xstrdup(oldmacros);

tests/rpmmacro.at

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@ AT_KEYWORDS([macros])
77

88
# .rpmmacros exists, new directory not
99
RPMTEST_CHECK([[
10-
rm -rf ~/.config/rpm ~/.rpmmacros
11-
touch ~/.rpmmacros
12-
rpm --showrc | awk '/^Macro path/{print(a[split($0,a,":")])}'
10+
runroot rm -rf /root/.config/rpm /root/.rpmmacros
11+
runroot touch /root/.rpmmacros
12+
runroot rpm --showrc | awk '/^Macro path/{print(a[split($0,a,":")])}'
13+
runroot rpm --showrc | awk '/^Macro path/{print(a[split($0,a,":")])}'
1314
]],
1415
[0],
1516
[~/.rpmmacros
17+
~/.config/rpm/macros
1618
],
17-
[])
19+
[warning: Migrated /root/.rpmmacros to /root/.config/rpm/macros (leaving a symlink)
20+
])
1821

1922
# prefer new style if it exists
2023
RPMTEST_CHECK([[
@@ -50,6 +53,61 @@ SOMENV=/tmp/somewhere rpm --macros "%{getenv:SOMENV}" --eval "%somewhere"
5053
[])
5154
RPMTEST_CLEANUP
5255

56+
RPMTEST_SETUP_RW([macro path])
57+
AT_KEYWORDS([convert .macros])
58+
RPMTEST_USER
59+
60+
runroot_user rm -f /home/$RPMUSER/.config/rpm
61+
runroot_user rm -f /home/$RPMUSER/.rpmmacros
62+
runroot_user rm -f /home/$RPMUSER/.rpmrc
63+
runroot_user bash -c "echo %foo bar > /home/$RPMUSER/.rpmmacros"
64+
runroot_user touch "/home/$RPMUSER/.rpmrc"
65+
66+
RPMTEST_CHECK([[
67+
runroot_user chmod 000 /home/$RPMUSER/.rpmmacros
68+
runroot_user rpm -E "%{foo}"
69+
runroot_user chmod 644 /home/$RPMUSER/.rpmmacros
70+
]],
71+
[0],
72+
[%{foo}
73+
],
74+
[error: Could not migrate /home/klang/.rpmmacros to /home/klang/.config/rpm/macros: Permission denied
75+
error: Could not migrate /home/klang/.rpmrc to /home/klang/.config/rpm/rpmrc: Permission denied
76+
])
77+
78+
RPMTEST_CHECK([[
79+
runroot_user chmod 000 /home/$RPMUSER/.rpmrc
80+
runroot_user rpm -E "%{foo}"
81+
runroot_user chmod 644 /home/$RPMUSER/.rpmrc
82+
]],
83+
[0],
84+
[bar
85+
],
86+
[error: Could not migrate /home/klang/.rpmmacros to /home/klang/.config/rpm/macros: Permission denied
87+
error: Could not migrate /home/klang/.rpmrc to /home/klang/.config/rpm/rpmrc: Permission denied
88+
])
89+
90+
RPMTEST_CHECK([[
91+
runroot_user readlink /home/$RPMUSER/.rpmmacros
92+
runroot_user readlink /home/$RPMUSER/.rpmrc
93+
runroot_user rpm -E "%{foo}"
94+
runroot_user readlink /home/$RPMUSER/.rpmmacros
95+
runroot_user readlink /home/$RPMUSER/.rpmrc
96+
runroot_user rpm -E "%{foo}"
97+
runroot_user rpm --showrc | awk '/^Macro path/{print(a[split($0,a,":")])}'
98+
]],
99+
[0],
100+
[bar
101+
.config/rpm/macros
102+
.config/rpm/rpmrc
103+
bar
104+
~/.config/rpm/macros
105+
],
106+
[warning: Migrated /home/klang/.rpmmacros to /home/klang/.config/rpm/macros (leaving a symlink)
107+
warning: Migrated /home/klang/.rpmrc to /home/klang/.config/rpm/rpmrc (leaving a symlink)
108+
])
109+
RPMTEST_CLEANUP
110+
53111
# ------------------------------
54112
RPMTEST_SETUP_RW([macro path: skip editor backups])
55113
AT_KEYWORDS([macros])

0 commit comments

Comments
 (0)