9a189abe94dd22c5859cde7d895f2cc09f6e0b0b
1 // $Id: unix_system.cxx,v 1.15 2003/07/25 13:16:04 grumbel Exp $
3 // Construo - A wire-frame construction game
4 // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 #include <sys/types.h>
33 #include "construo_error.hxx"
34 #include "string_utils.hxx"
35 #include "construo.hxx"
36 #include "path_manager.hxx"
37 #include "unix_system.hxx"
39 using namespace StringUtils
;
41 UnixSystem::UnixSystem ()
42 { // riped out of ClanLib-0.7
44 gettimeofday(&tv
, NULL
);
45 start_time
= (long) tv
.tv_sec
*(long) 1000+(long) tv
.tv_usec
/(long) 1000;
47 char* home
= getenv("HOME");
50 construo_rc_path
= std::string(home
) + std::string("/.construo/");
54 std::cout
<< "UnixSystem: FATAL ERROR: couldn't find env variable $HOME" << std::endl
;
55 throw ConstruoError ("UnixSystem: Couldn't find $HOME!");
58 // create $HOME directory if not already there
61 if (stat(construo_rc_path
.c_str(), &buf
) != 0) // Couldn't find directory, create it
63 if (mkdir(construo_rc_path
.c_str(), S_IRUSR
| S_IWUSR
| S_IXUSR
| S_IRGRP
| S_IXGRP
) != 0)
65 throw ConstruoError(std::string("UnixSystem: ") + construo_rc_path
+ ": "
71 if (S_ISDIR(buf
.st_rdev
)) // Is not a directory
73 throw ConstruoError("Error: " + construo_rc_path
+ " is not a directory!");
76 if (access(construo_rc_path
.c_str (), R_OK
| W_OK
| X_OK
) != 0) // not readable/writeable
78 throw ConstruoError("Error: " + construo_rc_path
+ " is not read or writeable!");
83 UnixSystem::~UnixSystem ()
88 UnixSystem::get_time ()
89 { // riped out of ClanLib-0.7
91 gettimeofday(&tv
, NULL
);
93 long tid
= (long) tv
.tv_sec
*(long) 1000 + (long) tv
.tv_usec
/(long) 1000 - start_time
;
99 UnixSystem::sleep (unsigned long t
)
105 UnixSystem::get_construo_rc_path()
107 std::cout
<< "Returning: \n" << construo_rc_path
<< std::endl
;
108 return construo_rc_path
;
112 UnixSystem::get_user_realname()
116 pw
= getpwuid(getuid());
128 UnixSystem::get_user_email()
130 const char* s_email
= getenv("EMAIL");
140 UnixSystem::get_mtime (const std::string
& filename
)
142 std::string sys_name
= translate_filename(filename
);
145 if (stat(sys_name
.c_str(), &buf
) != 0)
156 UnixSystem::get_file_type(const std::string
& filename
)
158 if (filename
== "/examples/"
159 || filename
== "/user/")
162 std::string sys_name
= translate_filename(filename
);
165 if (stat(sys_name
.c_str(), &buf
) != 0)
167 std::cout
<< "UnixSystem: ERROR: Couldn't stat: '" << sys_name
<< "'" << std::endl
;
168 return FT_UNKNOWN_FILE
;
172 if (S_ISDIR(buf
.st_mode
))
176 else if (S_ISREG(buf
.st_mode
))
178 if (has_suffix(filename
, ".construo") || has_suffix(filename
, ".construo.gz"))
179 return FT_CONSTRUO_FILE
;
182 return FT_UNKNOWN_FILE
;
187 return FT_UNKNOWN_FILE
;
193 UnixSystem::translate_filename (const std::string
& filename
)
197 assert("root directory is not translatable");
200 else if (has_prefix(filename
, "/user/"))
202 return construo_rc_path
+ filename
.substr(6);
204 else if (has_prefix(filename
, "/examples/"))
206 return path_manager
.complete("examples/") + filename
.substr(10);
213 UnixSystem::open_input_file(const std::string
& filename
)
215 std::cout
<< "UnixSystem: open_input_file: " << translate_filename (filename
) << std::endl
;
216 return fopen(translate_filename (filename
).c_str(), "r");
220 UnixSystem::open_output_file(const std::string
& filename
)
222 std::cout
<< "UnixSystem: open_output_file: " << translate_filename (filename
) << std::endl
;
223 return fopen(translate_filename (filename
).c_str(), "w");
227 /** Sort directories before files and sort them all
229 struct DirectorySorter
231 std::string pathname
;
233 DirectorySorter(const std::string
& p
)
238 bool operator()(const std::string
& lhs
, const std::string
& rhs
)
240 FileType lhs_type
= system_context
->get_file_type(pathname
+ "/" + lhs
);
241 FileType rhs_type
= system_context
->get_file_type(pathname
+ "/" + rhs
);
243 if (lhs_type
== rhs_type
)
245 else if (lhs_type
== FT_DIRECTORY
)
249 else if (rhs_type
== FT_DIRECTORY
)
260 std::vector
<std::string
>
261 UnixSystem::read_directory(const std::string
& arg_pathname
)
263 if (arg_pathname
== "/")
265 std::vector
<std::string
> ret
;
266 ret
.push_back("examples/");
267 ret
.push_back("user/");
272 std::vector
<std::string
> dir_lst
;
273 std::string pathname
= translate_filename (arg_pathname
);
275 DIR* dir
= ::opendir (pathname
.c_str());
279 std::cout
<< "UnixSystem: Error couldn't open: '" << pathname
<< "', ignoring\n"
280 << " error and continuing with an empty directory" << std::endl
;
284 struct dirent
* entry
;
286 while ((entry
= readdir(dir
)) != 0)
288 if (strcmp(entry
->d_name
, ".") != 0
289 && strcmp(entry
->d_name
, "..") != 0
290 && strcmp(entry
->d_name
, "CVS") != 0)
291 { // We ignore unusefull directories
292 dir_lst
.push_back(entry
->d_name
);
299 std::sort(dir_lst
.begin(), dir_lst
.end(), DirectorySorter(pathname
));