1 /**
2 * Copyright (c) 2008-2015 Alper Akcan <alper.akcan@gmail.com>
3 * Copyright (c) 2009 Renzo Davoli <renzo@cs.unibo.it>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program (in the main directory of the fuse-ext2
17 * distribution in the file COPYING); if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include "fuse-ext2.h"
22
op_symlink(const char * sourcename,const char * destname)23 int op_symlink (const char *sourcename, const char *destname)
24 {
25 int rt;
26 size_t wr;
27 ext2_file_t efile;
28 ext2_filsys e2fs = current_ext2fs();
29 int sourcelen = strlen(sourcename);
30
31 debugf("enter");
32 debugf("source: %s, dest: %s", sourcename, destname);
33
34 /* a short symlink is stored in the inode (recycling the i_block array) */
35 if (sourcelen < (EXT2_N_BLOCKS * sizeof(__u32))) {
36 rt = do_create(e2fs, destname, LINUX_S_IFLNK | 0777, 0, sourcename);
37 if (rt != 0) {
38 debugf("do_create(%s, LINUX_S_IFLNK | 0777, FAST); failed", destname);
39 return rt;
40 }
41 } else {
42 rt = do_create(e2fs, destname, LINUX_S_IFLNK | 0777, 0, NULL);
43 if (rt != 0) {
44 debugf("do_create(%s, LINUX_S_IFLNK | 0777); failed", destname);
45 return rt;
46 }
47 efile = do_open(e2fs, destname, O_WRONLY);
48 if (efile == NULL) {
49 debugf("do_open(%s); failed", destname);
50 return -EIO;
51 }
52 wr = do_write(efile, sourcename, sourcelen, 0);
53 if (wr != strlen(sourcename)) {
54 debugf("do_write(efile, %s, %d, 0); failed", sourcename, strlen(sourcename) + 1);
55 return -EIO;
56 }
57 rt = do_release(efile);
58 if (rt != 0) {
59 debugf("do_release(efile); failed");
60 return rt;
61 }
62 }
63 debugf("leave");
64 return 0;
65 }
66