3 * Copyright (C) 2002 Florin Malita <mali@go.ro>
5 * This file is part of LUFS, a free userspace filesystem implementation.
6 * See http://lufs.sourceforge.net/ for updates.
8 * LUFS is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * LUFS is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include <sys/types.h>
36 #include <sys/socket.h>
38 #include <sys/ioctl.h>
40 #include <sys/mount.h>
43 #include <lufs/proto.h>
48 #include "filesystem.h"
51 #define CONFIG_FILE1 "/etc/lufsd.conf"
52 #define CONFIG_FILE2 "~/.lufs/lufsd.conf"
54 const char *exec_paths[]={
55 "/usr/local/bin/lufsmnt",
62 tempsock(char *base, char *name){
63 struct sockaddr_un addr;
67 if((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){
68 ERROR("socket error: %s", strerror(errno));
72 addr.sun_family = AF_UNIX;
76 sprintf(addr.sun_path, "%s%lu", base, rnd);
78 TRACE("trying address %s", addr.sun_path);
80 res = bind(sock, (struct sockaddr*)&addr, sizeof(addr));
81 }while((res < 0) && (errno == EADDRINUSE));
84 ERROR("bind error: %s", strerror(errno));
88 if((res = listen(sock, 10)) < 0){
89 ERROR("listen error: %s", strerror(errno));
94 strcpy(name, addr.sun_path);
100 main(int argc, char **argv){
101 char *service, *mountpoint, *odata;
102 struct list_head cfg;
104 char tmp[256], *nopts;
105 int ssock, pid, mpid, res;
107 INIT_LIST_HEAD(&cfg);
113 if((argc < 5) || (strcmp(argv[3], "-o")) ){
114 ERROR("Usage: %s none <mount-point> -o [options, ...]", argv[0]);
119 TRACE("more options than expected...");
123 mountpoint = argv[2];
127 nopts = malloc(strlen(odata) + 100);
129 ERROR("out of memory!");
133 strcpy(nopts, odata);
135 if(lu_opt_parse(&cfg, "MOUNT", odata) < 0){
136 ERROR("could not parse options!");
140 if((lu_opt_loadcfg(&cfg, CONFIG_FILE1) < 0))
141 lu_opt_loadcfg(&cfg, CONFIG_FILE2);
143 if(!(ctl = lu_fsctl_create(&cfg))){
144 WARN("could not create fs_ctl!");
148 if(!lu_fsctl_mount(ctl)){
149 ERROR("could not mount filesystem!");
150 lu_fsctl_destroy(ctl);
154 if((ssock = tempsock("/tmp/lufsd", tmp)) < 0)
157 TRACE("starting filesystem master at %s", tmp);
159 chmod(tmp, S_IRWXU | S_IRWXG | S_IRWXO);
161 /* detach & launch FSCtl */
163 if((pid = fork()) < 0){
164 ERROR("fork failed!");
171 quiet = lu_opt_getchar(&cfg, "MOUNT", "quiet");
173 if((fd = open("/dev/tty", O_RDWR, 0)) < 0){
174 WARN("couldn't open tty, assuming still ok...");
177 ioctl(fd, TIOCNOTTY, 0);
187 TRACE("going dumb...");
188 if((stdfd = open("/dev/null", O_RDWR, 0)) < 0){
189 WARN("couldn't open /dev/null!");
198 /* launching FSCtl... */
199 lu_fsctl_run(ctl, ssock, tmp);
204 sprintf(nopts, "%s,server_socket=%s,server_pid=%d", nopts, tmp, pid);
206 /* execute lufsmnt and wait for it. */
208 if((mpid = fork()) < 0){
209 ERROR("fork failed!");
218 args[1] = mountpoint;
222 TRACE("executing %s %s %s", args[0], args[1], args[2]);
223 execvp("lufsmnt", args);
224 WARN("execvp of lufsmnt failed: %s", strerror(errno));
225 WARN("you don't seem to have lufsmnt in your path. trying regular locations...");
227 for(p = exec_paths[0]; p; p++){
228 TRACE("trying %s %s %s", p, args[1], args[2]);
232 ERROR("could not launch lufsmnt!\n");
236 if(waitpid(mpid, &res, 0) < 0){
237 ERROR("waitpid failed!");
242 if(WIFEXITED(res) && WEXITSTATUS(res) != 0){
247 TRACE("mount succeded");