1 /***************************************************************************
2 * Copyright (C) 2006 Kent Gustavsson <nedo80@gmail.com>
3 ****************************************************************************/
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.
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 Library General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 #define FUSE_USE_VERSION 25
34 #include "rararchive.h"
39 static int rarfs_getattr(const char *p
, struct stat
*stbuf
)
43 std::string path
= p
+ 1;
45 while ( (pos
= path
.find("/")) != std::string::npos
)
46 path
.replace(pos
,1,"\\");
48 memset(stbuf
, 0, sizeof(struct stat
));
49 if(strcmp(p
, "/") == 0)
51 stbuf
->st_mode
= S_IFDIR
| 0755;
54 arc
.GetDate(path
, &stbuf
->st_atim
);
55 arc
.GetDate(path
, &stbuf
->st_mtim
);
57 else if(arc
.HasFolder(path
))
59 stbuf
->st_mode
= S_IFDIR
| 0755;
61 arc
.GetDate(path
, &stbuf
->st_atim
);
62 arc
.GetDate(path
, &stbuf
->st_mtim
);
64 else if(arc
.HasFile(path
))
66 stbuf
->st_mode
= S_IFREG
| 0444;
68 stbuf
->st_size
= arc
.GetFileSize(path
);
69 arc
.GetDate(path
, &stbuf
->st_atim
);
70 arc
.GetDate(path
, &stbuf
->st_mtim
);
78 static int rarfs_readdir(const char *p
, void *buf
, fuse_fill_dir_t filler
,
79 off_t offset
, struct fuse_file_info
*fi
)
81 std::vector
<std::string
> list
= arc
.GetFiles();
82 std::vector
<std::string
>::iterator iter
;
83 std::map
< std::string
, int > ugly
;
85 std::string path
= p
+ 1;
87 while ( (pos
= path
.find("/")) != std::string::npos
)
88 path
.replace(pos
,1,"\\");
90 if(strcmp(p
, "/") != 0)
92 if (!arc
.HasFolder(path
))
96 filler(buf
, ".", NULL
, 0);
97 filler(buf
, "..", NULL
, 0);
99 for(iter
= list
.begin() ; iter
!= list
.end() ; iter
++)
101 if( iter
->size() > path
.size() )
103 if ( iter
->substr(0, path
.size()) == path
)
105 std::string file
= iter
->substr(path
.size());
106 if ( file
[0] == '\\' )
107 file
= file
.substr(1);
109 if( file
.find("\\") == std::string::npos
)
111 filler(buf
, file
.c_str(), NULL
, 0);
117 list
= arc
.GetFolders();
118 for(iter
= list
.begin() ; iter
!= list
.end() ; iter
++)
120 if( iter
->size() > path
.size() )
122 if ( iter
->substr(0, path
.size()) == path
)
124 std::string folder
= iter
->substr(path
.size());
125 if ( folder
[0] == '\\' )
126 folder
= folder
.substr(1);
127 folder
= folder
.substr(0, folder
.find("\\"));
133 std::map
<std::string
, int>::iterator ui
;
134 for( ui
= ugly
.begin() ; ui
!= ugly
.end() ; ui
++)
135 filler(buf
, ui
->first
.c_str(), NULL
, 0);
140 static int rarfs_open(const char *p
, fuse_file_info
*fi
)
142 std::string path
= p
+ 1;
144 while ( (pos
= path
.find("/")) != std::string::npos
)
145 path
.replace(pos
,1,"\\");
148 if(!arc
.HasFile(path
))
152 if((fi
->flags
& 3) != O_RDONLY
)
158 static int rarfs_read(const char *p
, char *buf
, size_t size
, off_t offset
, fuse_file_info
*fi
)
160 std::string path
= p
+ 1;
162 while ( (pos
= path
.find("/")) != std::string::npos
)
163 path
.replace(pos
,1,"\\");
166 if(!arc
.HasFile(path
))
169 return arc
.Read(path
.c_str(), buf
, size
, offset
) ;
172 static struct fuse_operations rarfs_oper
;
177 static void usage(char const* arg0
);
182 /* "Key" values for command-line options */
183 static const int KEY_HELP
= 0;
184 static const int KEY_VERSION
= 1;
186 static const int KEEP
= 1;
187 static const int DISCARD
= 0;
196 static struct fuse_opt rarfs_opts
[] = {
197 FUSE_OPT_KEY("-h", Opt::KEY_HELP
),
198 FUSE_OPT_KEY("--help", Opt::KEY_HELP
),
199 FUSE_OPT_KEY("-V", Opt::KEY_VERSION
),
200 FUSE_OPT_KEY("--version", Opt::KEY_VERSION
),
204 static int rarfs_opt_proc(void *data
, const char *arg
, int key
,
205 struct fuse_args
*outargs
)
207 Opt
*param
= static_cast<Opt
*>(data
);
210 case FUSE_OPT_KEY_NONOPT
:
211 if( param
->rarfile
[0] == 0 )
213 strcpy(param
->rarfile
, arg
);
219 Opt::usage(outargs
->argv
[0]);
222 /* Copied from usage() in helper.c in Fuse 2.9.0 */
225 " -o opt,[opt...] mount options\n"
226 " -h --help print help\n"
227 " -V --version print version\n"
230 /* Substitute "help without header" option for fuse_
233 ret
= fuse_opt_add_arg(outargs
, "-ho");
239 param
->mount_expected
= false;
242 case Opt::KEY_VERSION
:
243 fputs(PACKAGE
" " VERSION
"\n", stderr
);
244 param
->mount_expected
= false;
251 void Opt::usage(char const* arg0
)
253 fprintf(stderr
, "USAGE: %s <file> <dir>\n", arg0
);
256 int main( int argc
, char ** argv
)
259 struct fuse_args args
= FUSE_ARGS_INIT(argc
, argv
);
262 if (fuse_opt_parse(&args
, ¶m
, rarfs_opts
, rarfs_opt_proc
) == -1)
265 if ( param
.mount_expected
)
267 if ( ! arc
.Init(param
.rarfile
) )
273 rarfs_oper
.getattr
= rarfs_getattr
;
274 rarfs_oper
.readdir
= rarfs_readdir
;
275 rarfs_oper
.open
= rarfs_open
;
276 rarfs_oper
.read
= rarfs_read
;
281 return fuse_main(args
.argc
, args
.argv
, &rarfs_oper
);