00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifdef HAVE_CONFIG_H
00040 #include <config.h>
00041 #endif
00042
00043 #include <cctype>
00044 #include <cstdlib>
00045
00046 #include <string>
00047
00048 #ifdef HAVE_UNISTD_H
00049 #ifdef HAVE_SYS_TYPES_H
00050 #include <sys/types.h>
00051 #endif
00052 #include <unistd.h>
00053 #endif
00054
00055 #include "file-ops.h"
00056 #include "lo-error.h"
00057 #include "lo-sysdep.h"
00058 #include "lo-utils.h"
00059 #include "oct-env.h"
00060 #include "oct-passwd.h"
00061 #include "oct-syscalls.h"
00062
00063 octave_env::octave_env (void)
00064 : follow_symbolic_links (true), verbatim_pwd (true),
00065 current_directory (), program_name (), program_invocation_name (),
00066 user_name (), host_name ()
00067 {
00068
00069 do_getcwd ();
00070
00071
00072 do_get_user_name ();
00073
00074 do_get_host_name ();
00075 }
00076
00077 octave_env *octave_env::instance = 0;
00078
00079 bool
00080 octave_env::instance_ok (void)
00081 {
00082 bool retval = true;
00083
00084 if (! instance)
00085 instance = new octave_env ();
00086
00087 if (! instance)
00088 {
00089 (*current_liboctave_error_handler)
00090 ("unable to create current working directoy object!");
00091
00092 retval = false;
00093 }
00094
00095 return retval;
00096 }
00097
00098 std::string
00099 octave_env::polite_directory_format (const std::string& name)
00100 {
00101 return (instance_ok ())
00102 ? instance->do_polite_directory_format (name) : std::string ();
00103 }
00104
00105 bool
00106 octave_env::absolute_pathname (const std::string& s)
00107 {
00108 return (instance_ok ())
00109 ? instance->do_absolute_pathname (s) : false;
00110 }
00111
00112 std::string
00113 octave_env::base_pathname (const std::string& s)
00114 {
00115 return (instance_ok ())
00116 ? instance->do_base_pathname (s) : std::string ();
00117 }
00118
00119 std::string
00120 octave_env::make_absolute (const std::string& s, const std::string& dot_path)
00121 {
00122 return (instance_ok ())
00123 ? instance->do_make_absolute (s, dot_path) : std::string ();
00124 }
00125
00126 std::string
00127 octave_env::getcwd ()
00128 {
00129 return (instance_ok ())
00130 ? instance->do_getcwd () : std::string ();
00131 }
00132
00133 std::string
00134 octave_env::get_home_directory ()
00135 {
00136 return (instance_ok ())
00137 ? instance->do_get_home_directory () : std::string ();
00138 }
00139
00140 std::string
00141 octave_env::get_program_name (void)
00142 {
00143 return (instance_ok ())
00144 ? instance->program_name : std::string ();
00145 }
00146
00147 std::string
00148 octave_env::get_program_invocation_name (void)
00149 {
00150 return (instance_ok ())
00151 ? instance->program_invocation_name : std::string ();
00152 }
00153
00154 void
00155 octave_env::set_program_name (const std::string& s)
00156 {
00157 if (instance_ok ())
00158 instance->do_set_program_name (s);
00159 }
00160
00161 std::string
00162 octave_env::get_user_name (void)
00163 {
00164 return (instance_ok ())
00165 ? instance->do_get_user_name () : std::string ();
00166 }
00167
00168 std::string
00169 octave_env::get_host_name (void)
00170 {
00171 return (instance_ok ())
00172 ? instance->do_get_host_name () : std::string ();
00173 }
00174
00175
00176
00177
00178
00179 std::string
00180 octave_env::getenv (const std::string& name)
00181 {
00182 return (instance_ok ())
00183 ? instance->do_getenv (name) : std::string ();
00184 }
00185
00186 void
00187 octave_env::putenv (const std::string& name, const std::string& value)
00188 {
00189 octave_putenv (name, value);
00190 }
00191
00192 bool
00193 octave_env::chdir (const std::string& newdir)
00194 {
00195 return (instance_ok ())
00196 ? instance->do_chdir (newdir) : false;
00197 }
00198
00199 void
00200 octave_env::do_set_program_name (const std::string& s) const
00201 {
00202 program_invocation_name = s;
00203
00204 size_t pos = program_invocation_name.find_last_of (file_ops::dir_sep_chars);
00205
00206 program_name = (pos == NPOS)
00207 ? program_invocation_name : program_invocation_name.substr (pos+1);
00208 }
00209
00210
00211
00212
00213 std::string
00214 octave_env::do_polite_directory_format (const std::string& name) const
00215 {
00216 std::string retval;
00217
00218 std::string home_dir = do_get_home_directory ();
00219
00220 size_t len = home_dir.length ();
00221
00222 if (len > 1 && home_dir == name.substr (0, len)
00223 && (name.length () == len || file_ops::is_dir_sep (name[len])))
00224 {
00225 retval = "~";
00226 retval.append (name.substr (len));
00227 }
00228 else
00229 retval = name;
00230
00231 return retval;
00232 }
00233
00234 bool
00235 octave_env::do_absolute_pathname (const std::string& s) const
00236 {
00237 size_t len = s.length ();
00238
00239 if (len == 0)
00240 return false;
00241
00242 if (file_ops::is_dir_sep (s[0]))
00243 return true;
00244
00245 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM)
00246 if ((len == 2 && isalpha (s[0]) && s[1] == ':')
00247 || (len > 2 && isalpha (s[0]) && s[1] == ':'
00248 && file_ops::is_dir_sep (s[2])))
00249 return true;
00250 #endif
00251
00252 return false;
00253 }
00254
00255
00256
00257
00258
00259 std::string
00260 octave_env::do_base_pathname (const std::string& s) const
00261 {
00262 if (! do_absolute_pathname (s))
00263 return s;
00264
00265 size_t pos = s.find_last_of (file_ops::dir_sep_chars);
00266
00267 if (pos == NPOS)
00268 return s;
00269 else
00270 return s.substr (pos+1);
00271 }
00272
00273
00274
00275
00276 std::string
00277 octave_env::do_make_absolute (const std::string& s,
00278 const std::string& dot_path) const
00279 {
00280 #if defined (__EMX__)
00281 if (s.length () > 1 && s[1] == ':')
00282 return s;
00283 #endif
00284
00285 if (dot_path.empty () || s.empty () || do_absolute_pathname (s))
00286 return s;
00287
00288 std::string current_dir = dot_path;
00289
00290 if (current_dir.empty ())
00291 current_dir = do_getcwd ();
00292
00293 size_t pos = current_dir.length () - 1;
00294
00295 if (! file_ops::is_dir_sep (current_dir[pos]))
00296 current_dir.append (file_ops::dir_sep_str);
00297
00298
00299
00300 size_t i = 0;
00301 size_t slen = s.length ();
00302
00303 while (i < slen)
00304 {
00305 if (s[i] == '.')
00306 {
00307 if (i + 1 == slen)
00308 return current_dir;
00309
00310 if (file_ops::is_dir_sep (s[i+1]))
00311 {
00312 i += 2;
00313 continue;
00314 }
00315
00316 if (s[i+1] == '.'
00317 && (i + 2 == slen || file_ops::is_dir_sep (s[i+2])))
00318 {
00319 i += 2;
00320
00321 if (i != slen)
00322 i++;
00323
00324 pathname_backup (current_dir, 1);
00325
00326 continue;
00327 }
00328 }
00329
00330 size_t tmp = s.find_first_of (file_ops::dir_sep_chars, i);
00331
00332 if (tmp == NPOS)
00333 {
00334 current_dir.append (s, i, tmp-i);
00335 break;
00336 }
00337 else
00338 {
00339 current_dir.append (s, i, tmp-i+1);
00340 i = tmp + 1;
00341 }
00342 }
00343
00344 return current_dir;
00345 }
00346
00347
00348
00349 std::string
00350 octave_env::do_getcwd () const
00351 {
00352 if (! follow_symbolic_links)
00353 current_directory = "";
00354
00355 if (verbatim_pwd || current_directory.empty ())
00356 current_directory = ::octave_getcwd ();
00357
00358 return current_directory;
00359 }
00360
00361
00362
00363
00364 std::string
00365 octave_env::do_get_home_directory (void) const
00366 {
00367 std::string hd = do_getenv ("HOME");
00368
00369 if (hd.empty ())
00370 {
00371 octave_passwd pw = octave_passwd::getpwuid (octave_syscalls::getuid ());
00372
00373 hd = pw ? pw.dir () : std::string (file_ops::dir_sep_str);
00374 }
00375
00376 return hd;
00377 }
00378
00379 std::string
00380 octave_env::do_get_user_name (void) const
00381 {
00382
00383
00384
00385 if (user_name.empty ())
00386 {
00387 octave_passwd pw = octave_passwd::getpwuid (octave_syscalls::getuid ());
00388
00389 user_name = pw ? pw.name () : std::string ("unknown");
00390 }
00391
00392 return user_name;
00393 }
00394
00395 std::string
00396 octave_env::do_get_host_name (void) const
00397 {
00398
00399
00400
00401 if (host_name.empty ())
00402 {
00403 char hostname[256];
00404
00405 int status = octave_gethostname (hostname, 255);
00406
00407 host_name = (status < 0) ? "unknown" : hostname;
00408 }
00409
00410 return host_name;
00411 }
00412
00413 std::string
00414 octave_env::do_getenv (const std::string& name) const
00415 {
00416 char *value = ::getenv (name.c_str ());
00417
00418 return value ? value : "";
00419 }
00420
00421
00422
00423
00424 bool
00425 octave_env::do_chdir (const std::string& newdir)
00426 {
00427 bool retval = false;
00428
00429 std::string tmp;
00430
00431 if (follow_symbolic_links)
00432 {
00433 if (current_directory.empty ())
00434 do_getcwd ();
00435
00436 if (current_directory.empty ())
00437 tmp = newdir;
00438 else
00439 tmp = do_make_absolute (newdir, current_directory);
00440
00441
00442
00443 size_t len = tmp.length ();
00444
00445 if (len > 1)
00446 {
00447 if (file_ops::is_dir_sep (tmp[--len]))
00448 tmp.resize (len);
00449 }
00450
00451 if (! ::octave_chdir (tmp))
00452 {
00453 current_directory = tmp;
00454 retval = true;
00455 }
00456 }
00457 else
00458 retval = (! ::octave_chdir (newdir));
00459
00460 return retval;
00461 }
00462
00463
00464
00465 void
00466 octave_env::pathname_backup (std::string& path, int n) const
00467 {
00468 if (path.empty ())
00469 return;
00470
00471 size_t i = path.length () - 1;
00472
00473 while (n--)
00474 {
00475 while (file_ops::is_dir_sep (path[i]) && i > 0)
00476 i--;
00477
00478 while (! file_ops::is_dir_sep (path[i]) && i > 0)
00479 i--;
00480
00481 i++;
00482 }
00483
00484 path.resize (i);
00485 }
00486
00487 void
00488 octave_env::error (int err_num) const
00489 {
00490 (*current_liboctave_error_handler) ("%s", strerror (err_num));
00491 }
00492
00493 void
00494 octave_env::error (const std::string& s) const
00495 {
00496 (*current_liboctave_error_handler) ("%s", s.c_str ());
00497 }
00498
00499
00500
00501
00502
00503