aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgramanas <anastasis.gramm2@gmail.com>2018-10-27 12:35:07 +0300
committergramanas <anastasis.gramm2@gmail.com>2018-10-27 12:39:01 +0300
commit2922690b716540b7e3971ffbdf506148503c7788 (patch)
treeccb6a4dbbffadf5f91ee47ca5ef5bd8347c02a1c
parent1b09a70af6096d2f85cadff82f227e4e6850bfda (diff)
downloadck-2922690b716540b7e3971ffbdf506148503c7788.tar.gz
ck-2922690b716540b7e3971ffbdf506148503c7788.tar.bz2
ck-2922690b716540b7e3971ffbdf506148503c7788.zip
change own&grp when it should. version 0.8.1!
-rw-r--r--CMakeLists.txt4
-rw-r--r--README.html209
-rw-r--r--README.org33
-rw-r--r--src/actionhelper.c44
-rw-r--r--src/actions.c7
-rw-r--r--src/ckerrlog.h5
-rw-r--r--src/ckutil.c27
-rw-r--r--src/ckutil.h3
8 files changed, 237 insertions, 95 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4327f84..1ed42c6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,8 +12,8 @@ cmake_minimum_required (VERSION 3.5.6)
project(ck C)
# version
set(ck_MAJOR_VERSION 0)
-set(ck_MINOR_VERSION 7)
-set(ck_PATCH_VERSION 14)
+set(ck_MINOR_VERSION 8)
+set(ck_PATCH_VERSION 1)
# Feature test macros
set(FEATURE_TEST_MACROS "-D_DEFAULT_SOURCE")
diff --git a/README.html b/README.html
index dc25609..d22b910 100644
--- a/README.html
+++ b/README.html
@@ -3,7 +3,7 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
-<!-- 2018-10-26 Fri 16:01 -->
+<!-- 2018-10-27 Sat 12:38 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>&lrm;</title>
@@ -232,40 +232,41 @@ for the JavaScript code in this tag.
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
-<li><a href="#org521fe12">ck</a>
+<li><a href="#orgbe0f74b">ck</a>
<ul>
-<li><a href="#orga2a199d">Technicalities</a></li>
-<li><a href="#orge675bb7">Download</a></li>
+<li><a href="#orgf6d327c">Technicalities</a></li>
+<li><a href="#org2964151">Download</a></li>
</ul>
</li>
<li><a href="#build-instructions">build it</a>
<ul>
-<li><a href="#orgc421406">requirements</a></li>
-<li><a href="#orga4dab6e">make &amp;&amp; install</a></li>
+<li><a href="#orgcd68bd4">requirements</a></li>
+<li><a href="#orgd88abc4">make &amp;&amp; install</a></li>
</ul>
</li>
-<li><a href="#orge2205a2">for devs</a>
+<li><a href="#org915da5a">for devs</a>
<ul>
-<li><a href="#org5f75c37">CMake options</a></li>
-<li><a href="#orgac3cc9e">compiler</a></li>
-<li><a href="#org32fde8e">tests</a>
+<li><a href="#org00bd7c0">CMake options</a></li>
+<li><a href="#orgc80ed25">compiler</a></li>
+<li><a href="#orgb421f08">tests</a>
<ul>
-<li><a href="#orgf37899e">run tests</a></li>
-<li><a href="#orgff9613a">test suite</a></li>
+<li><a href="#org099faaf">run tests</a></li>
+<li><a href="#org0c9b8e4">test suite</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#manual">manual</a>
<ul>
-<li><a href="#org8bc297f">ck configuration</a></li>
-<li><a href="#orgfb252e7">Actions</a>
+<li><a href="#org80abd4c">ck configuration</a></li>
+<li><a href="#org367dc64">Actions</a>
<ul>
-<li><a href="#org0bde617">init</a></li>
-<li><a href="#orge38e9d6">add</a></li>
-<li><a href="#org224e52f">list</a></li>
-<li><a href="#org21ebeec">search</a></li>
-<li><a href="#orgb56bde4">edit</a></li>
+<li><a href="#org2ddbc86">init</a></li>
+<li><a href="#orgb007d62">add</a></li>
+<li><a href="#orgf17f83b">list</a></li>
+<li><a href="#orgc6b731f">search</a></li>
+<li><a href="#org7f65c8f">edit</a></li>
+<li><a href="#org8e0dc74">restore</a></li>
</ul>
</li>
</ul>
@@ -274,9 +275,9 @@ for the JavaScript code in this tag.
</div>
</div>
<p align="center"><img src="res/logo.png"></p>
-<div id="outline-container-org521fe12" class="outline-2">
-<h2 id="org521fe12">ck</h2>
-<div class="outline-text-2" id="text-org521fe12">
+<div id="outline-container-orgbe0f74b" class="outline-2">
+<h2 id="orgbe0f74b">ck</h2>
+<div class="outline-text-2" id="text-orgbe0f74b">
<p>
<b>The Config Keeper</b>
</p>
@@ -332,9 +333,9 @@ with the rest of us).
</p>
</div>
-<div id="outline-container-orga2a199d" class="outline-3">
-<h3 id="orga2a199d">Technicalities</h3>
-<div class="outline-text-3" id="text-orga2a199d">
+<div id="outline-container-orgf6d327c" class="outline-3">
+<h3 id="orgf6d327c">Technicalities</h3>
+<div class="outline-text-3" id="text-orgf6d327c">
<p>
Upon adding a config to <b>ck</b>, it moves it to the specified folder and adds a symbolic link
back where it came from (<code>ln -s</code>).
@@ -347,9 +348,9 @@ majority should).
</div>
</div>
-<div id="outline-container-orge675bb7" class="outline-3">
-<h3 id="orge675bb7">Download</h3>
-<div class="outline-text-3" id="text-orge675bb7">
+<div id="outline-container-org2964151" class="outline-3">
+<h3 id="org2964151">Download</h3>
+<div class="outline-text-3" id="text-org2964151">
<p>
Go ahead and download <b>ck</b> and give it a try. It comes with a help sub-command
that explains any inquires you might have.
@@ -367,13 +368,13 @@ You can also read the manual <a href="#manual">down below</a>.
</div>
</div>
-<div id="outline-container-orga8e0de1" class="outline-2">
-<h2 id="build-instructions"><a id="orga8e0de1"></a>build it</h2>
+<div id="outline-container-org905a4f4" class="outline-2">
+<h2 id="build-instructions"><a id="org905a4f4"></a>build it</h2>
<div class="outline-text-2" id="text-build-instructions">
</div>
-<div id="outline-container-orgc421406" class="outline-3">
-<h3 id="orgc421406">requirements</h3>
-<div class="outline-text-3" id="text-orgc421406">
+<div id="outline-container-orgcd68bd4" class="outline-3">
+<h3 id="orgcd68bd4">requirements</h3>
+<div class="outline-text-3" id="text-orgcd68bd4">
<ul class="org-ul">
<li>cmake</li>
<li>sqlite3-dev</li>
@@ -382,9 +383,9 @@ You can also read the manual <a href="#manual">down below</a>.
</div>
</div>
-<div id="outline-container-orga4dab6e" class="outline-3">
-<h3 id="orga4dab6e">make &amp;&amp; install</h3>
-<div class="outline-text-3" id="text-orga4dab6e">
+<div id="outline-container-orgd88abc4" class="outline-3">
+<h3 id="orgd88abc4">make &amp;&amp; install</h3>
+<div class="outline-text-3" id="text-orgd88abc4">
<p>
Use <code>-DCMAKE_INSTALL_PREFIX</code> when running cmake to change the install path.
</p>
@@ -407,16 +408,16 @@ Use <code>-DCMAKE_INSTALL_PREFIX</code> when running cmake to change the install
</div>
</div>
-<div id="outline-container-orge2205a2" class="outline-2">
-<h2 id="orge2205a2">for devs</h2>
-<div class="outline-text-2" id="text-orge2205a2">
+<div id="outline-container-org915da5a" class="outline-2">
+<h2 id="org915da5a">for devs</h2>
+<div class="outline-text-2" id="text-org915da5a">
<p>
Please be <a href="https://www.gnu.org/philosophy/kind-communication.html">kind</a> to each other.
</p>
</div>
-<div id="outline-container-org5f75c37" class="outline-3">
-<h3 id="org5f75c37">CMake options</h3>
-<div class="outline-text-3" id="text-org5f75c37">
+<div id="outline-container-org00bd7c0" class="outline-3">
+<h3 id="org00bd7c0">CMake options</h3>
+<div class="outline-text-3" id="text-org00bd7c0">
<p>
cmake accepts the following options:
</p>
@@ -437,9 +438,9 @@ To use any one of them append it after the cmake command like so:
</div>
</div>
-<div id="outline-container-orgac3cc9e" class="outline-3">
-<h3 id="orgac3cc9e">compiler</h3>
-<div class="outline-text-3" id="text-orgac3cc9e">
+<div id="outline-container-orgc80ed25" class="outline-3">
+<h3 id="orgc80ed25">compiler</h3>
+<div class="outline-text-3" id="text-orgc80ed25">
<p>
Pick your favorite
</p>
@@ -469,9 +470,9 @@ Pick your favorite
</div>
</div>
-<div id="outline-container-org32fde8e" class="outline-3">
-<h3 id="org32fde8e">tests</h3>
-<div class="outline-text-3" id="text-org32fde8e">
+<div id="outline-container-orgb421f08" class="outline-3">
+<h3 id="orgb421f08">tests</h3>
+<div class="outline-text-3" id="text-orgb421f08">
<p>
The testing "suite" is a bash script that runs regression
and unit tests. Regression tests are under the <code>tests/</code> directory
@@ -480,9 +481,9 @@ under <code>unit/</code> directory and test the code.
</p>
</div>
-<div id="outline-container-orgf37899e" class="outline-4">
-<h4 id="orgf37899e">run tests</h4>
-<div class="outline-text-4" id="text-orgf37899e">
+<div id="outline-container-org099faaf" class="outline-4">
+<h4 id="org099faaf">run tests</h4>
+<div class="outline-text-4" id="text-org099faaf">
<p>
First make sure you build ck with the <code>-DCK_TESTS=1</code> option. Then
go to the build directory and type:
@@ -494,9 +495,9 @@ go to the build directory and type:
</div>
</div>
-<div id="outline-container-orgff9613a" class="outline-4">
-<h4 id="orgff9613a">test suite</h4>
-<div class="outline-text-4" id="text-orgff9613a">
+<div id="outline-container-org0c9b8e4" class="outline-4">
+<h4 id="org0c9b8e4">test suite</h4>
+<div class="outline-text-4" id="text-org0c9b8e4">
<div class="org-src-container">
<pre class="src src-sh">$ ./test-ck -h
ck test suite
@@ -514,8 +515,8 @@ flags:
</div>
</div>
</div>
-<div id="outline-container-org68d2b05" class="outline-2">
-<h2 id="manual"><a id="org68d2b05"></a>manual</h2>
+<div id="outline-container-org4e88e4b" class="outline-2">
+<h2 id="manual"><a id="org4e88e4b"></a>manual</h2>
<div class="outline-text-2" id="text-manual">
<p>
ck's goal is to assist with the configuration file management.
@@ -567,9 +568,9 @@ of flags one has to pass to ck.
</p>
</div>
-<div id="outline-container-org8bc297f" class="outline-3">
-<h3 id="org8bc297f">ck configuration</h3>
-<div class="outline-text-3" id="text-org8bc297f">
+<div id="outline-container-org80abd4c" class="outline-3">
+<h3 id="org80abd4c">ck configuration</h3>
+<div class="outline-text-3" id="text-org80abd4c">
<p>
ck uses sqlite to index the configuration files. The init
action creates a <b>.ck</b> directory (under <code>$HOME</code>)
@@ -607,13 +608,13 @@ $ ck -c /someplace/else ...
</div>
</div>
-<div id="outline-container-orgfb252e7" class="outline-3">
-<h3 id="orgfb252e7">Actions</h3>
-<div class="outline-text-3" id="text-orgfb252e7">
+<div id="outline-container-org367dc64" class="outline-3">
+<h3 id="org367dc64">Actions</h3>
+<div class="outline-text-3" id="text-org367dc64">
</div>
-<div id="outline-container-org0bde617" class="outline-4">
-<h4 id="org0bde617">init</h4>
-<div class="outline-text-4" id="text-org0bde617">
+<div id="outline-container-org2ddbc86" class="outline-4">
+<h4 id="org2ddbc86">init</h4>
+<div class="outline-text-4" id="text-org2ddbc86">
<p>
or i or -i
</p>
@@ -643,9 +644,9 @@ $ ck init /path_to/where_you_want/your_configs/to_be <span style="color: #bdbc61
</div>
</div>
-<div id="outline-container-orge38e9d6" class="outline-4">
-<h4 id="orge38e9d6">add</h4>
-<div class="outline-text-4" id="text-orge38e9d6">
+<div id="outline-container-orgb007d62" class="outline-4">
+<h4 id="orgb007d62">add</h4>
+<div class="outline-text-4" id="text-orgb007d62">
<p>
or a or -a
</p>
@@ -686,9 +687,9 @@ $ ck add program_name config_path [-s] [-p]
</div>
</div>
-<div id="outline-container-org224e52f" class="outline-4">
-<h4 id="org224e52f">list</h4>
-<div class="outline-text-4" id="text-org224e52f">
+<div id="outline-container-orgf17f83b" class="outline-4">
+<h4 id="orgf17f83b">list</h4>
+<div class="outline-text-4" id="text-orgf17f83b">
<p>
or ls or l or -l
</p>
@@ -751,9 +752,9 @@ $ ck -l ckconf
</div>
</div>
-<div id="outline-container-org21ebeec" class="outline-4">
-<h4 id="org21ebeec">search</h4>
-<div class="outline-text-4" id="text-org21ebeec">
+<div id="outline-container-orgc6b731f" class="outline-4">
+<h4 id="orgc6b731f">search</h4>
+<div class="outline-text-4" id="text-orgc6b731f">
<p>
or grep or s or -s
</p>
@@ -802,9 +803,9 @@ $ for i ($(ck ls paths)) grep -E <span style="color: #bdbc61;">'A|B'</span> $<sp
</div>
</div>
-<div id="outline-container-orgb56bde4" class="outline-4">
-<h4 id="orgb56bde4">edit</h4>
-<div class="outline-text-4" id="text-orgb56bde4">
+<div id="outline-container-org7f65c8f" class="outline-4">
+<h4 id="org7f65c8f">edit</h4>
+<div class="outline-text-4" id="text-org7f65c8f">
<p>
or e or -e
</p>
@@ -849,11 +850,63 @@ $ ck edit emacs accounts.el
</div>
</div>
</div>
+
+<div id="outline-container-org8e0dc74" class="outline-4">
+<h4 id="org8e0dc74">restore</h4>
+<div class="outline-text-4" id="text-org8e0dc74">
+<p>
+or r or -r
+</p>
+
+<p>
+Restore links.
+</p>
+
+<p>
+Given a working ck instance (ckdb + ckrc + directories in ckrc with configs)
+restore shall recreate the links from the config directories in ckrc
+back to their corresponding position when added in ck.
+</p>
+
+<p>
+It is useful for copying your configs to a new linux installation
+or restoring deleted links.
+</p>
+
+<p>
+It can either restore a specific program or all of them:
+</p>
+<div class="org-src-container">
+<pre class="src src-sh"><span style="color: #656565;"># </span><span style="color: #757575;">restore progName</span>
+ck restore -p progName
+<span style="color: #656565;"># </span><span style="color: #757575;">restore all</span>
+ck r all
+</pre>
+</div>
+
+<p>
+Note:
+If ck tracks configs that are owned by root, simply running
+`ck restore &#x2026;` will fail due to permissions. To remedy this, ck will alter the
+owner and group of a link to match the one in the ckrc directories.
+Thus, running `sudo ck -c <i>home/myuser</i>.ck restore ..` will restore
+the root user's links as it should and the user links will have
+the user as the owner instead of the root.
+</p>
+
+<p>
+ck checks that the configs exist and that the location for the link
+is avaliable before making any links. However, in the even that symlink
+fails for some other reason, the process will stop as is. Make sure you
+take care of the already created links, if that's the case.
+</p>
+</div>
+</div>
</div>
</div>
</div>
<div id="postamble" class="status">
-<p class="date">Created: 2018-10-26 Fri 16:01</p>
+<p class="date">Created: 2018-10-27 Sat 12:38</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>
diff --git a/README.org b/README.org
index 7d5e4d7..3e1c20f 100644
--- a/README.org
+++ b/README.org
@@ -354,3 +354,36 @@ $ ck edit emacs
# edit a specific emacs config, other than the primary
$ ck edit emacs accounts.el
#+END_SRC
+
+*** restore
+or r or -r
+
+Restore links.
+
+Given a working ck instance (ckdb + ckrc + directories in ckrc with configs)
+restore shall recreate the links from the config directories in ckrc
+back to their corresponding position when added in ck.
+
+It is useful for copying your configs to a new linux installation
+or restoring deleted links.
+
+It can either restore a specific program or all of them:
+#+BEGIN_SRC sh
+ # restore progName
+ ck restore -p progName
+ # restore all
+ ck r all
+#+END_SRC
+
+Note:
+If ck tracks configs that are owned by root, simply running
+`ck restore ...` will fail due to permissions. To remedy this, ck will alter the
+owner and group of a link to match the one in the ckrc directories.
+Thus, running `sudo ck -c /home/myuser/.ck restore ..` will restore
+the root user's links as it should and the user links will have
+the user as the owner instead of the root.
+
+ck checks that the configs exist and that the location for the link
+is avaliable before making any links. However, in the even that symlink
+fails for some other reason, the process will stop as is. Make sure you
+take care of the already created links, if that's the case.
diff --git a/src/actionhelper.c b/src/actionhelper.c
index 0269470..6428ab0 100644
--- a/src/actionhelper.c
+++ b/src/actionhelper.c
@@ -266,19 +266,25 @@ int restore_make_links(cklist *from, cklist *to) {
if (list_size(from) > 0
&& list_size(to) > 0
&& list_size(from) == list_size(to)) {
- while (1) {
- HELP("%s %d %d", list_get(to), util_file_exists(list_get(to), NULL), !util_is_file_link(list_get(to)));
+ do {
if (util_file_exists(list_get(to), NULL)
|| !util_is_file_link(list_get(to))) {
- sERR("File %s already exists. Terminating.", list_get(to));
+ ERR("File %s already exists.", list_get(to));
+ sERR("No links were created.");
return -1;
}
+ } while (list_next(to));
+ list_rewind(to);
+ while (1) {
if (util_symlink_file(list_get(from), list_get(to))) {
- sERR("Failed: %s -> %s", list_get(from), list_get(to));
+ ERR("FATAL could not link %s -> %s", list_get(from), list_get(to));
+ sERR("Process stopping.");
+ return -1;
+ }
+ hLOG("Linking: %s -> %s", list_get(from), list_get(to));
+ if (util_own_grp_copy(list_get(to), list_get(from))) {
return -1;
}
- LOG("Linking: %s -> %s", list_get(from), list_get(to));
- HELP("Linking: %s -> %s", list_get(from), list_get(to));
if (!list_next(from)) {
break;
}
@@ -348,11 +354,9 @@ void print_HELP_result(int err) {
}
void print_RESTORE_result(int err) {
- if (!err) {
- HELP("restore OK");
- return;
+ if (err == -1) {
+ sERR("Restore failed.")
}
- sERR("restore NOT OK");
}
void print_INIT_help() {
@@ -445,7 +449,25 @@ void print_HELP_help() {
}
void print_RESTORE_help() {
- ckhelp("Restore help");
+ ckhelp("Restore links.\n");
+ ckhelp("Given a working ck instance (ckdb + ckrc + directories in ckrc with configs)");
+ ckhelp("restore shall recreate the links from the config directories in ckrc");
+ ckhelp("back to their corresponding position when added in ck.\n");
+ ckhelp("It is useful for copying your configs to a new linux installation");
+ ckhelp("or restoring deleted links.\n");
+ ckhelp("It can either restore a specific program or all of them:");
+ ckhelp(" `-p progName`: restores progName.");
+ ckhelp(" `all`: restores everything.\n");
+ ckhelp("Note:\nIf ck tracks configs that are owned by root, simply running");
+ ckhelp("`ck restore ...` will fail due to permissions. To remedy this, ck will alter the");
+ ckhelp("owner and group of a link to match the one in the ckrc directories.");
+ ckhelp("Thus, running `sudo ck -c /home/myuser/.ck restore ..` will restore");
+ ckhelp("the root user's links as it should and the user links will have");
+ ckhelp("the user as the owner instead of the root.\n");
+ ckhelp("ck checks that the configs exist and that the location for the link");
+ ckhelp("is avaliable before making any links. However, in the even that symlink");
+ ckhelp("fails for some other reason, the process will stop as is. Make sure you");
+ ckhelp("take care of the already created links, if that's the case.");
report_help();
}
diff --git a/src/actions.c b/src/actions.c
index 5220864..649ffb8 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -317,7 +317,7 @@ int run_RESTORE(UserOpt *opt, Conf *conf) {
if (list_next(opt->args)) {
if (program_exists(&db, list_get(opt->args))) {
if (restore_configs_exists(&db, conf, list_get(opt->args), from, to)) {
- HELP("Making links for %s", list_get(opt->args));
+ hLOG("Restoring links for %s...", list_get(opt->args));
}
else {
err_flag = 1;
@@ -336,7 +336,7 @@ int run_RESTORE(UserOpt *opt, Conf *conf) {
else if (strcmp(list_get(opt->args), "all") == 0) {
if (!list_next(opt->args)) {
if (restore_all_exist(&db, conf, from, to)) {
- HELP("Make all links");
+ hLOG("Restoring all links...");
}
else {
err_flag = 1;
@@ -353,7 +353,6 @@ int run_RESTORE(UserOpt *opt, Conf *conf) {
}
close_DB(&db);
if (!err_flag) {
- HELP("LINKS");
int rc = restore_make_links(from, to);
list_free(from);
list_free(to);
@@ -361,5 +360,5 @@ int run_RESTORE(UserOpt *opt, Conf *conf) {
}
list_free(from);
list_free(to);
- return 1;
+ return -2;
}
diff --git a/src/ckerrlog.h b/src/ckerrlog.h
index 9d71458..bf0c0a5 100644
--- a/src/ckerrlog.h
+++ b/src/ckerrlog.h
@@ -90,5 +90,10 @@ CK_STREAMS
cklog_with_delim(" ", "[%s]", COMPONENT); \
cklog(__VA_ARGS__);
+/* Print help message & log it */
+#define hLOG(...) \
+ HELP(__VA_ARGS__); \
+ LOG(__VA_ARGS__);
+
#define LOG_V(...)
#endif /* CKERRLOG_H */
diff --git a/src/ckutil.c b/src/ckutil.c
index 84eb43d..f292e8e 100644
--- a/src/ckutil.c
+++ b/src/ckutil.c
@@ -17,6 +17,9 @@
#include <unistd.h>
#include "ckutil.h"
+#include "ckerrlog.h"
+
+ERRLOG(utility);
int util_is_dir(const char *path) {
if (!path) {
@@ -153,3 +156,27 @@ int str_is_empty(const char *s) {
}
return 1;
}
+
+int util_own_grp_copy(const char *dest, const char *original) {
+ if (!dest || !original) {
+ return -1;
+ }
+ struct stat destbuf, origbuf;
+ if (lstat(dest, &destbuf)) {
+ sERR("error stating %s", dest)
+ return -1;
+ }
+ if (stat(original, &origbuf)) {
+ sERR("error stating %s", original)
+ return -1;
+ }
+ if (destbuf.st_uid != origbuf.st_uid
+ || destbuf.st_gid != origbuf.st_gid) {
+ hLOG("Copying uid & gid: %s -> %s", original, dest);
+ if (lchown(dest, origbuf.st_uid, origbuf.st_gid)) {
+ sERR("Cannot change owner and group of %s", dest);
+ return -1;
+ }
+ }
+ return 0;
+}
diff --git a/src/ckutil.h b/src/ckutil.h
index dde7665..d653116 100644
--- a/src/ckutil.h
+++ b/src/ckutil.h
@@ -90,4 +90,7 @@ extern int util_move_file(const char *path, const char* dest);
/* Wrapper around symlink() */
extern int util_symlink_file(const char *path, const char* dest);
+
+/* Chnage owner and group of `new` and make it like `old`*/
+extern int util_own_grp_copy(const char *new, const char* old);
#endif // CKUTIL_H