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