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"
38 static int rarfs_getattr(const char *p
, struct stat
*stbuf
)
42 std::string path
= p
+ 1;
44 while ( (pos
= path
.find("/")) != std::string::npos
)
45 path
.replace(pos
,1,"\\");
47 memset(stbuf
, 0, sizeof(struct stat
));
48 if(strcmp(p
, "/") == 0)
50 stbuf
->st_mode
= S_IFDIR
| 0755;
53 arc
.GetDate(path
, &stbuf
->st_atim
);
54 arc
.GetDate(path
, &stbuf
->st_mtim
);
56 else if(arc
.HasFolder(path
))
58 stbuf
->st_mode
= S_IFDIR
| 0755;
60 arc
.GetDate(path
, &stbuf
->st_atim
);
61 arc
.GetDate(path
, &stbuf
->st_mtim
);
63 else if(arc
.HasFile(path
))
65 stbuf
->st_mode
= S_IFREG
| 0444;
67 stbuf
->st_size
= arc
.GetFileSize(path
);
68 arc
.GetDate(path
, &stbuf
->st_atim
);
69 arc
.GetDate(path
, &stbuf
->st_mtim
);
77 static int rarfs_readdir(const char *p
, void *buf
, fuse_fill_dir_t filler
,
78 off_t offset
, struct fuse_file_info
*fi
)
80 std::vector
<std::string
> list
= arc
.GetFiles();
81 std::vector
<std::string
>::iterator iter
;
82 std::map
< std::string
, int > ugly
;
84 std::string path
= p
+ 1;
86 while ( (pos
= path
.find("/")) != std::string::npos
)
87 path
.replace(pos
,1,"\\");
89 if(strcmp(p
, "/") != 0)
91 if (!arc
.HasFolder(path
))
95 filler(buf
, ".", NULL
, 0);
96 filler(buf
, "..", NULL
, 0);
98 for(iter
= list
.begin() ; iter
!= list
.end() ; iter
++)
100 if( iter
->size() > path
.size() )
102 if ( iter
->substr(0, path
.size()) == path
)
104 std::string file
= iter
->substr(path
.size());
105 if ( file
[0] == '\\' )
106 file
= file
.substr(1);
108 if( file
.find("\\") == std::string::npos
)
110 filler(buf
, file
.c_str(), NULL
, 0);
116 list
= arc
.GetFolders();
117 for(iter
= list
.begin() ; iter
!= list
.end() ; iter
++)
119 if( iter
->size() > path
.size() )
121 if ( iter
->substr(0, path
.size()) == path
)
123 std::string folder
= iter
->substr(path
.size());
124 if ( folder
[0] == '\\' )
125 folder
= folder
.substr(1);
126 folder
= folder
.substr(0, folder
.find("\\"));
132 std::map
<std::string
, int>::iterator ui
;
133 for( ui
= ugly
.begin() ; ui
!= ugly
.end() ; ui
++)
134 filler(buf
, ui
->first
.c_str(), NULL
, 0);
139 static int rarfs_open(const char *p
, fuse_file_info
*fi
)
141 std::string path
= p
+ 1;
143 while ( (pos
= path
.find("/")) != std::string::npos
)
144 path
.replace(pos
,1,"\\");
147 if(!arc
.HasFile(path
))
151 if((fi
->flags
& 3) != O_RDONLY
)
157 static int rarfs_read(const char *p
, char *buf
, size_t size
, off_t offset
, fuse_file_info
*fi
)
159 std::string path
= p
+ 1;
161 while ( (pos
= path
.find("/")) != std::string::npos
)
162 path
.replace(pos
,1,"\\");
165 if(!arc
.HasFile(path
))
168 return arc
.Read(path
.c_str(), buf
, size
, offset
) ;
171 static struct fuse_operations rarfs_oper
;
180 static const int KEEP
= 1;
181 static const int DISCARD
= 0;
190 static struct fuse_opt rarfs_opts
[] = {
193 static int rarfs_opt_proc(void *data
, const char *arg
, int key
,
194 struct fuse_args
*outargs
)
196 Opt
*param
= static_cast<Opt
*>(data
);
199 case FUSE_OPT_KEY_NONOPT
:
200 if( param
->rarfile
[0] == 0 )
202 strcpy(param
->rarfile
, arg
);
211 int main( int argc
, char ** argv
)
214 struct fuse_args args
= FUSE_ARGS_INIT(argc
, argv
);
217 if (fuse_opt_parse(&args
, ¶m
, rarfs_opts
, rarfs_opt_proc
) == -1)
220 if ( param
.mount_expected
)
222 if ( ! arc
.Init(param
.rarfile
) )
224 printf("USAGE: %s <file> <dir>\n", argv
[0]);
228 rarfs_oper
.getattr
= rarfs_getattr
;
229 rarfs_oper
.readdir
= rarfs_readdir
;
230 rarfs_oper
.open
= rarfs_open
;
231 rarfs_oper
.read
= rarfs_read
;
236 return fuse_main(args
.argc
, args
.argv
, &rarfs_oper
);