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);
111 if((argc < 5) || (strcmp(argv[3], "-o")) ){
112 ERROR("Usage: %s none <mount-point> -o [options, ...]", argv[0]);
117 TRACE("more options than expected...");
121 mountpoint = argv[2];
125 nopts = malloc(strlen(odata) + 100);
127 ERROR("out of memory!");
131 strcpy(nopts, odata);
133 if(lu_opt_parse(&cfg, "MOUNT", odata) < 0){
134 ERROR("could not parse options!");
138 if((lu_opt_loadcfg(&cfg, CONFIG_FILE1) < 0))
139 lu_opt_loadcfg(&cfg, CONFIG_FILE2);
141 if(!(ctl = lu_fsctl_create(&cfg))){
142 WARN("could not create fs_ctl!");
146 if(!lu_fsctl_mount(ctl)){
147 ERROR("could not mount filesystem!");
148 lu_fsctl_destroy(ctl);
152 if((ssock = tempsock("/tmp/lufsd", tmp)) < 0)
155 TRACE("starting filesystem master at %s", tmp);
157 chmod(tmp, S_IRWXU | S_IRWXG | S_IRWXO);
159 /* detach & launch FSCtl */
161 if((pid = fork()) < 0){
162 ERROR("fork failed!");
169 quiet = lu_opt_getchar(&cfg, "MOUNT", "quiet");
171 if((fd = open("/dev/tty", O_RDWR, 0)) < 0){
172 WARN("couldn't open tty, assuming still ok...");
175 ioctl(fd, TIOCNOTTY, 0);
185 TRACE("going dumb...");
186 if((stdfd = open("/dev/null", O_RDWR, 0)) < 0){
187 WARN("couldn't open /dev/null!");
196 /* launching FSCtl... */
197 lu_fsctl_run(ctl, ssock, tmp);
202 sprintf(nopts, "%s,server_socket=%s,server_pid=%d", nopts, tmp, pid);
204 /* execute lufsmnt and wait for it. */
206 if((mpid = fork()) < 0){
207 ERROR("fork failed!");
216 args[1] = mountpoint;
220 TRACE("executing %s %s %s", args[0], args[1], args[2]);
221 execvp("lufsmnt", args);
222 WARN("execvp of lufsmnt failed: %s", strerror(errno));
223 WARN("you don't seem to have lufsmnt in your path. trying regular locations...");
225 for(p = exec_paths[0]; p; p++){
226 TRACE("trying %s %s %s", p, args[1], args[2]);
230 ERROR("could not launch lufsmnt!\n");
234 if(waitpid(mpid, &res, 0) < 0){
235 ERROR("waitpid failed!");
240 if(WIFEXITED(res) && WEXITSTATUS(res) != 0){
245 TRACE("mount succeded");