Encapsulate “rarfile” parameter in “Opt” class
[rarfs.git] / src / main.cc
blobcb2a0d0b2b0f14e54285687e475307d73494efbc
1 /***************************************************************************
2 * Copyright (C) 2006 Kent Gustavsson <nedo80@gmail.com>
3 ****************************************************************************/
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.
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
21 #include <fuse.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <fuse_opt.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <cstdlib>
31 #include <iostream>
32 #include <fstream>
33 #include "rarblock.h"
34 #include "rararchive.h"
36 RARArchive arc;
38 static int rarfs_getattr(const char *p, struct stat *stbuf)
40 int res = 0;
42 std::string path = p + 1;
43 int pos;
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;
51 stbuf->st_nlink = 2;
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;
59 stbuf->st_nlink = 2;
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;
66 stbuf->st_nlink = 1;
67 stbuf->st_size = arc.GetFileSize(path);
68 arc.GetDate(path, &stbuf->st_atim);
69 arc.GetDate(path, &stbuf->st_mtim);
71 else
72 res = -ENOENT;
74 return res;
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;
85 int pos;
86 while ( (pos = path.find("/")) != std::string::npos )
87 path.replace(pos,1,"\\");
89 if(strcmp(p, "/") != 0)
91 if (!arc.HasFolder(path))
92 return -ENOENT;
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("\\"));
127 ugly[folder] = 1;
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);
136 return 0;
139 static int rarfs_open(const char *p, fuse_file_info *fi)
141 std::string path = p + 1;
142 int pos;
143 while ( (pos = path.find("/")) != std::string::npos )
144 path.replace(pos,1,"\\");
147 if(!arc.HasFile(path))
148 return -ENOENT;
151 if((fi->flags & 3) != O_RDONLY)
152 return -EACCES;
154 return 0;
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;
160 int pos;
161 while ( (pos = path.find("/")) != std::string::npos )
162 path.replace(pos,1,"\\");
164 size_t len;
165 if(!arc.HasFile(path))
166 return -ENOENT;
168 return arc.Read(path.c_str(), buf, size, offset) ;
171 static struct fuse_operations rarfs_oper;
173 struct Opt
175 Opt();
177 char rarfile[512];
178 bool mount_expected;
180 static const int KEEP = 1;
181 static const int DISCARD = 0;
184 Opt::Opt() :
185 mount_expected(true)
187 rarfile[0] = 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);
198 switch (key) {
199 case FUSE_OPT_KEY_NONOPT:
200 if( param->rarfile[0] == 0 )
202 strcpy(param->rarfile, arg);
203 return Opt::DISCARD;
205 break;
208 return Opt::KEEP;
211 int main( int argc, char ** argv)
214 struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
215 Opt param;
217 if (fuse_opt_parse(&args, &param, rarfs_opts, rarfs_opt_proc) == -1)
218 exit(1);
220 if ( param.mount_expected )
222 if ( ! arc.Init(param.rarfile) )
224 printf("USAGE: %s <file> <dir>\n", argv[0]);
225 return -1;
228 rarfs_oper.getattr = rarfs_getattr;
229 rarfs_oper.readdir = rarfs_readdir;
230 rarfs_oper.open = rarfs_open;
231 rarfs_oper.read = rarfs_read;
233 arc.Parse(false);
236 return fuse_main(args.argc, args.argv, &rarfs_oper);