1 /*
2 * cook - file construction tool
3 * Copyright (C) 2007 Peter Miller;
4 * All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20
21 #include <common/ac/errno.h>
22 #include <common/ac/unistd.h>
23
24 #include <common/error_intl.h>
25 #include <cook/os_interface.h>
26
27
28 int
os_symlink(string_ty * from,string_ty * to,int echo)29 os_symlink(string_ty *from, string_ty *to, int echo)
30 {
31 int err;
32
33 err = symlink(from->str_text, to->str_text);
34 if (err)
35 {
36 char link_content[2000];
37
38 if (errno != EEXIST)
39 {
40 sub_context_ty *scp;
41
42 whine:
43 scp = sub_context_new();
44 sub_var_set_string(scp, "File_Name_1", from);
45 sub_var_set_string(scp, "File_Name_2", to);
46 error_intl(scp, i18n("symlink($filename1, $filename2): $errno"));
47 sub_context_delete(scp);
48 return -1;
49 }
50 err = readlink(to->str_text, link_content, sizeof(link_content));
51 if (err < 0)
52 {
53 if (errno != EINVAL)
54 {
55 sub_context_ty *scp;
56
57 scp = sub_context_new();
58 sub_var_set_string(scp, "File_Name", to);
59 error_intl(scp, i18n("readlink \"$filename\": $errno"));
60 sub_context_delete(scp);
61 return -1;
62 }
63 }
64 else
65 {
66 string_ty *s2;
67 int ok;
68
69 s2 = str_n_from_c(link_content, err);
70 ok = str_equal(s2, from);
71 str_free(s2);
72 if (ok)
73 return 0;
74 }
75 err = unlink(to->str_text);
76 if (err < 0)
77 {
78 error_intl_unlink(to->str_text);
79 return -1;
80 }
81
82 if (echo)
83 {
84 sub_context_ty *scp;
85
86 scp = sub_context_new();
87 sub_var_set_string(scp, "File_Name", to);
88 error_intl(scp, i18n("rm $filename"));
89 sub_context_delete(scp);
90 }
91
92 err = symlink(from->str_text, to->str_text);
93 if (err < 0)
94 goto whine;
95 }
96 if (echo)
97 {
98 sub_context_ty *scp;
99
100 scp = sub_context_new();
101 sub_var_set_string(scp, "File_Name_1", from);
102 sub_var_set_string(scp, "File_Name_2", to);
103 error_intl(scp, i18n("ln -s $filename1 $filename2"));
104 sub_context_delete(scp);
105 }
106 return 0;
107 }
108