source: rrlib_util/sFileIOUtils.cpp @ 136:53211ebe7c86

Last change on this file since 136:53211ebe7c86 was 136:53211ebe7c86, checked in by Tobias Föhst <foehst@…>, 4 years ago

Merge with 13.10

File size: 28.0 KB
Line 
1//
2// You received this file as part of RRLib
3// Robotics Research Library
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    rrlib/util/sFileIOUtils.cpp
23 *
24 * \author  Bernd Helge Schaefer
25 * \author  Jens Wettach
26 * \author  Tim Braun
27 *
28 * \date    2005-11-15
29 *
30 */
31//----------------------------------------------------------------------
32// Includes
33//----------------------------------------------------------------------
34#include "rrlib/util/sFileIOUtils.h"
35
36#include <algorithm>
37#include <iostream>
38#include <fstream>
39#include <sstream>
40#include <iterator>
41
42extern "C"
43{
44#include <netdb.h> // struct hostent, gethostbyname
45#include <unistd.h>
46#include <dirent.h>
47#include <wordexp.h>
48}
49
50#include "rrlib/util/sStringUtils.h"
51#include "rrlib/util/join.h"
52#include "rrlib/logging/messages.h"
53
54//----------------------------------------------------------------------
55// Debug
56//----------------------------------------------------------------------
57#include <cassert>
58#include <cstring>
59#include <cerrno>
60
61//----------------------------------------------------------------------
62// Namespace usage
63//----------------------------------------------------------------------
64using namespace std;
65
66//----------------------------------------------------------------------
67// Namespace declaration
68//----------------------------------------------------------------------
69namespace rrlib
70{
71namespace util
72{
73
74//----------------------------------------------------------------------
75// initialization of static class vars
76//----------------------------------------------------------------------
77std::string sFileIOUtils::cached_local_host = "";
78std::map<std::string, std::string> sFileIOUtils::host_name_to_ip_cache = std::map<std::string, std::string>();
79std::map<std::string, std::string> sFileIOUtils::resource_cache = std::map<std::string, std::string>();
80
81
82
83bool sFileIOUtils::GetAllFilesInDirectory(std::string dir, std::vector<std::string> &files)
84{
85  DIR *dp;
86  struct dirent *dirp;
87  if ((dp  = opendir(dir.c_str())) == NULL)
88  {
89    return false;
90  }
91
92  while ((dirp = readdir(dp)) != NULL)
93  {
94    files.push_back(std::string(dirp->d_name));
95    //std::cout << "Found: " << dirp->d_name << std::endl;
96  }
97
98  closedir(dp);
99  return true;
100}
101
102
103
104//----------------------------------------------------------------------
105// class sFileIOUtils::GetCurrentDirectory()
106//----------------------------------------------------------------------
107std::string sFileIOUtils::GetCurrentDirectory()
108{
109  char *temp_path(NULL);
110  // POSIX.1 extension allocates buffer for path if given buffer is NULL and size = 0
111  temp_path = getcwd(temp_path, 0);
112  std::string path(temp_path);
113  path += "/";
114  free(temp_path);
115  return path;
116}
117
118//----------------------------------------------------------------------
119// class sFileIOUtils::ChangeCurrentDirectory()
120//----------------------------------------------------------------------
121int sFileIOUtils::ChangeCurrentDirectory(const std::string& dir)
122{
123  return chdir(dir.c_str());
124}
125
126//----------------------------------------------------------------------
127// class sFileIOUtils::CreateDirectory()
128//----------------------------------------------------------------------
129bool sFileIOUtils::CreateDirectory(const std::string& path)    //throw(runtime_error)
130{
131  std::stringstream sys_call;
132  sys_call << "mkdir -p " << path;
133
134  if (system(sys_call.str().c_str()) == -1)
135  {
136    RRLIB_LOG_PRINT(USER, "sFileIOUtils>> Error creating dir: '", path, "'");
137//     std::stringstream error_msg;
138//     error_msg << "sFileIOUtils>> Error creating Dir:\n"
139//     << path << endl;
140    //throw runtime_error(error_msg.str());
141    return false;
142  }
143  else
144  {
145//     RRLIB_LOG_PRINT(USER, "Directory: '", path, "' successfully created.");
146    return true;
147  }
148}
149
150//----------------------------------------------------------------------
151// class sFileIOUtils::CreateTempfile()
152//----------------------------------------------------------------------
153std::string sFileIOUtils::CreateTempfile()
154{
155  FILE * pipe = popen("mktemp", "r");
156  char buf[ 1024 ];
157  if (fgets(buf, sizeof(buf), pipe) == 0)
158  {
159    RRLIB_LOG_PRINT(ERROR, "Error creating temp file!");
160    exit(EXIT_FAILURE);
161  }
162  std::string tempfile = buf;
163  tempfile = tempfile.substr(0, tempfile.find("\n"));
164  pclose(pipe);
165  return tempfile;
166} // CreateTempfile()
167
168//----------------------------------------------------------------------
169// class sFileIOUtils::DeleteFile()
170//----------------------------------------------------------------------
171void sFileIOUtils::DeleteFile(const std::string& filename)
172{
173  unlink(filename.c_str());
174} // DeleteFile()
175
176//----------------------------------------------------------------------
177// class sFileIOUtils::CompressFile()
178//----------------------------------------------------------------------
179void sFileIOUtils::CompressFile(const std::string& input_filename, std::string& output_filename)
180{
181  if (!sStringUtils::EndsWith(output_filename, ".gz"))
182    output_filename += ".gz";
183  std::stringstream cmd;
184  cmd << "gzip -c " << input_filename << " > " << output_filename;
185  if (system(cmd.str().c_str()) != 0)
186  {
187    RRLIB_LOG_PRINT(ERROR, "Execution of command '", cmd.str(), "' failed!");
188    exit(EXIT_FAILURE);
189  }
190} // CompressFile()
191
192//----------------------------------------------------------------------
193// class sFileIOUtils::DecompressFile()
194//----------------------------------------------------------------------
195void sFileIOUtils::DecompressFile(const std::string& input_filename, const std::string& output_filename)
196{
197  assert(sStringUtils::EndsWith(input_filename, ".gz"));
198  std::stringstream cmd;
199  cmd << "gunzip -c " << input_filename << " > " << output_filename;
200  if (system(cmd.str().c_str()) != 0)
201  {
202    RRLIB_LOG_PRINT(ERROR, "Execution of command '", cmd.str(), "' failed!");
203    exit(EXIT_FAILURE);
204  }
205} // DecompressFile()
206
207//----------------------------------------------------------------------
208// class sFileIOUtils::FileExists()
209//----------------------------------------------------------------------
210bool sFileIOUtils::FileExists(const std::string &filename)
211{
212  // catch empty file
213  if (filename == "")
214  {
215    return false;
216  }
217
218  // test if file exists
219  FILE* file = fopen(filename.c_str(), "rb");
220  if (file == 0)
221  {
222    return false;
223  }
224  fclose(file);
225
226  return true;
227} // FileExists()
228
229
230//----------------------------------------------------------------------
231// class sFileIOUtils::CountLineNumbers()
232//----------------------------------------------------------------------
233size_t sFileIOUtils::CountLineNumbers(const std::string &filename)
234{
235  std::ifstream file(filename);
236  return std::count(std::istreambuf_iterator<char>(file),
237                    std::istreambuf_iterator<char>(), '\n');
238} // CountLineNumbers()
239
240
241
242//----------------------------------------------------------------------
243// class sFileIOUtils::ShellExpandFilename()
244//----------------------------------------------------------------------
245bool sFileIOUtils::ShellExpandFilename(std::string &file_name)
246{
247  return ShellExpandFilename(file_name, file_name);
248} // ShellExpandFilename()
249
250//----------------------------------------------------------------------
251// class sFileIOUtils::ShellExpandFilename()
252//----------------------------------------------------------------------
253std::string sFileIOUtils::ShellExpandFilename(const std::string &file_name)
254{
255  std::string result("");
256  if (ShellExpandFilename(result, file_name))
257    return result;
258  else
259    return "";
260} // ShellExpandFilename()
261
262
263//----------------------------------------------------------------------
264// class sFileIOUtils::ShellExpandFilename()
265//----------------------------------------------------------------------
266bool sFileIOUtils::ShellExpandFilename(std::string &result, const std::string &file_name)
267{
268  //result = "";  //in case &result == &file_name, then it causes trouble.
269  wordexp_t expansion;
270  int error = wordexp(file_name.c_str(), &expansion, WRDE_SHOWERR | WRDE_UNDEF);
271  if (error)
272  {
273    const char *error_msg = 0;
274    switch (error)
275    {
276    case WRDE_BADCHAR:
277      error_msg = "Illegal occurrence of newline or one of |, &, ;, <, >, (, ), {, }";
278      break;
279    case WRDE_BADVAL:
280      error_msg = "An undefined shell variable was referenced";
281      break;
282    case WRDE_NOSPACE:
283      error_msg = "Out of memory";
284      break;
285    case WRDE_SYNTAX:
286      error_msg = "Shell syntax error, such as unbalanced parentheses or unmatched quotes";
287      break;
288    default:
289      error_msg = "Unknown error";
290    }
291    RRLIB_LOG_PRINT(ERROR, "Could not expand '", file_name, "': ", error_msg, "!");
292    return false;
293  }
294
295  std::stringstream stream;
296  stream << util::Join(expansion.we_wordv + expansion.we_offs, expansion.we_wordv + expansion.we_offs + expansion.we_wordc, " ");
297  wordfree(&expansion);
298
299  result = stream.str();
300
301  return true;
302} // ShellExpandFilename()
303
304//----------------------------------------------------------------------
305// class sFileIOUtils::SplitFullQualifiedFilename()
306//----------------------------------------------------------------------
307void sFileIOUtils::SplitFullQualifiedFilename(const std::string& complete_name, std::string& file_dir, std::string& file_base, std::string& file_ext)
308{
309
310  std::string::size_type pos_slash = complete_name.find_last_of("/");
311  std::string::size_type pos_name = pos_slash + 1;
312
313  if (pos_slash == std::string::npos)
314  {
315    // no slash found
316    file_dir = "./";
317    pos_name = 0;
318    pos_slash = 0;
319  }
320  else
321  {
322    file_dir = complete_name.substr(0, pos_slash);
323  }
324
325  //    cerr << "pos_slash: " << pos_slash << endl;
326  std::string::size_type pos_dot = complete_name.find_last_of(".");
327  if (pos_dot == std::string::npos || pos_dot < pos_slash)
328  {
329    // no dot found or dot in directory
330    file_base = complete_name.substr(pos_name);
331    file_ext = "";
332  }
333  else
334  {
335    file_base = complete_name.substr(pos_name, pos_dot - pos_name);
336    file_ext = complete_name.substr(pos_dot);
337  }
338
339} // SplitFullQualifiedFilename()
340
341
342//----------------------------------------------------------------------
343// class sFileIOUtils::GetHostName()
344//----------------------------------------------------------------------
345std::string sFileIOUtils::GetHostName()
346{
347  char name[1024];
348  int result = gethostname(name, 1024);
349  if (result)
350  {
351    RRLIB_LOG_PRINT(ERROR, "got error: <", strerror(errno), ">");
352    exit(EXIT_FAILURE);
353  }
354  RRLIB_LOG_PRINT(DEBUG, "got hostname: <", name, ">");
355
356  return name;
357} // GetHostName()
358
359//----------------------------------------------------------------------
360// class sFileIOUtils::HostToIpViaGetHostByName()
361//----------------------------------------------------------------------
362struct ::in_addr sFileIOUtils::HostToIpViaGetHostByName(const std::string& name)
363{
364  struct in_addr address;
365  address.s_addr = 0;
366  struct hostent *host_ent = gethostbyname(name.c_str());       //alternative (from kernel/tTCPSocket): GetHostByName( name );
367  if (host_ent)
368  {
369    address = * ((struct in_addr *) host_ent->h_addr_list[ 0 ]);
370    RRLIB_LOG_PRINT(USER, "ip address of host <", name, "> = <", inet_ntoa(address), ">");
371  }
372  else
373  {
374    RRLIB_LOG_PRINT(ERROR, "could not get ip address of host <", name, ">");
375  }
376  return address;
377} //HostToIpViaGetHostByName()
378
379
380//----------------------------------------------------------------------
381// class sFileIOUtils::HostToIpViaNslookup()
382//----------------------------------------------------------------------
383struct in_addr sFileIOUtils::HostToIpViaNslookup(const std::string & name)
384{
385  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "started with host <", name, ">");
386  struct in_addr address;
387  address.s_addr = 0;
388
389  std::stringstream command;
390  command << "nslookup \"" << name << "\"";
391  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "command = <", command, ">");
392  FILE * pipe = popen(command.str().c_str(), "r");
393  if (!pipe)
394  {
395    perror("error\n");
396    return address;
397  }
398  std::stringstream result;
399  char buf[ 512 ];
400  while (fgets(buf, 512, pipe) != NULL)
401  {
402    result << buf;
403  }
404  pclose(pipe);
405  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "host = <", name, ">, result = <", result.str(), ">");
406
407  std::string result_str(result.str());
408  std::string search_token("Name:");
409  std::string::size_type pos = result_str.find(search_token);
410  if (pos == std::string::npos)
411  {
412    RRLIB_LOG_PRINT(ERROR, "Could not find token <", search_token, "> in nslookup result ... returning <", inet_ntoa(address), ">");
413    return address;
414  }
415  result_str.erase(0, pos + search_token.length());
416  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "pos = ", pos);
417
418  search_token = "Address:";
419  pos = result_str.find(search_token);
420  if (pos == std::string::npos)
421  {
422    RRLIB_LOG_PRINT(ERROR, "Could not find token <", search_token, "> in nslookup result ... returning <", inet_ntoa(address), ">");
423    return address;
424  }
425  RRLIB_LOG_PRINT(USER, "pos = ", pos);
426
427  std::string found_name(result_str.substr(0, pos));
428  sStringUtils::TrimWhitespace(found_name);
429  std::string ip(result_str.substr(pos + search_token.length()));
430  sStringUtils::TrimWhitespace(ip);
431
432  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "found_name <", found_name, "> , name <", name, ">");
433
434  if (found_name != name)
435  {
436    RRLIB_LOG_PRINT(ERROR, "nslookup failed .... returning <", inet_ntoa(address), ">");
437    return address;
438  }
439  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "found_name <", found_name, "> , ip <", ip, ">");
440
441  inet_aton(ip.c_str(), &address);
442
443  return address;
444} // HostToIpViaNslookup()
445
446
447//----------------------------------------------------------------------
448// class sFileIOUtils::HostToIpViaHost()
449//----------------------------------------------------------------------
450struct in_addr sFileIOUtils::HostToIpViaHost(const std::string & name)
451{
452  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "started with host <", name, ">");
453  struct in_addr address;
454  address.s_addr = 0;
455
456  std::stringstream command;
457  command << "host -t A \"" << name << "\"";
458  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "command = <", command.str(), ">");
459  FILE * pipe = popen(command.str().c_str(), "r");
460  if (!pipe)
461  {
462    perror("error\n");
463    return address;
464  }
465  std::stringstream result;
466  char buf[ 512 ];
467  while (fgets(buf, 512, pipe) != NULL)
468  {
469    result << buf;
470  }
471  pclose(pipe);
472  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "host = <", name, "> , result = <", result.str(), ">");
473
474  string result_str(result.str());
475  string search("has address");
476  size_t pos = result_str.find(search);
477  if (pos == string::npos)
478  {
479    RRLIB_LOG_PRINT(ERROR, "could not find address token in host call");
480    return address;
481  }
482  string address_str(result_str.substr(pos + search.size(), result_str.size()));
483  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "token = <", address_str, ">");
484  sStringUtils::TrimWhitespace(address_str);
485  if (inet_aton(address_str.c_str(), &address) == 0)
486    RRLIB_LOG_PRINT(ERROR, "could not resolve address <", address_str, ">");
487  else
488    RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "address = <", inet_ntoa(address), ">");
489  return address;
490} // HostToIpViaHost()
491
492//----------------------------------------------------------------------
493// class sFileIOUtils::HostToIpViaHostsFile()
494//----------------------------------------------------------------------
495struct in_addr sFileIOUtils::HostToIpViaHostsFile(const std::string & name)
496{
497  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "started with host <", name, ">");
498  struct in_addr address;
499  address.s_addr = 0;
500
501  ifstream hosts_file("/etc/hosts");
502
503  char line[ 1024 ];
504  std::string line_str, ip_address;
505  std::vector<std::string> tokens;
506  bool found(false);
507  while (!hosts_file.eof() && !found)
508  {
509    hosts_file.getline(line, 1024);
510    line_str = std::string(line);
511    if (line_str.length() > 0 && line_str.find("#") == std::string::npos)
512    {
513      tokens.clear();
514      sStringUtils::Tokenize(line_str, tokens, " \t");
515
516      if (find(tokens.begin(), tokens.end(), name) != tokens.end())
517      {
518        for (std::vector<std::string>::const_iterator iter = tokens.begin(); iter != tokens.end(); ++iter)
519        {
520          if (inet_aton(iter->c_str(), &address))
521          {
522            ip_address = *iter;
523            RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "sFileIOUtils::HostToIpViaHostsFile() >>> got ip <", ip_address, "> of host <", name, "> from hosts file");
524            found = true;
525            break;
526          }
527        }
528      }
529    }
530  }
531  hosts_file.close();
532  return address;
533} // HostToIpViaHostsFile()
534
535
536//----------------------------------------------------------------------
537// class sFileIOUtils::HostToIp()
538//----------------------------------------------------------------------
539struct in_addr sFileIOUtils::HostToIp(const std::string & name)
540{
541  RRLIB_LOG_PRINT(USER, "started with host <", name, ">");
542
543  struct in_addr address;
544  address.s_addr = 0;
545
546  if ((address = sFileIOUtils::HostToIpViaHostsFile(name)).s_addr != 0)
547  {
548    RRLIB_LOG_PRINT(USER, "got ip <", inet_ntoa(address), "> of host <", name, "> from hosts_file");
549  }
550  else if ((address = sFileIOUtils::HostToIpViaHost(name)).s_addr != 0)
551  {
552    RRLIB_LOG_PRINT(USER, "got ip <", inet_ntoa(address), "> of host <", name, "> via <host -t A>");
553  }
554  else if ((address = sFileIOUtils::HostToIpViaNslookup(name)).s_addr != 0)
555  {
556    RRLIB_LOG_PRINT(USER, "got ip <", inet_ntoa(address), "> of host <", name, "> via <nslookup>");
557  }
558  else
559  {
560    RRLIB_LOG_PRINT(ERROR, "could not get ip of host <", name, ">");
561  }
562
563  return address;
564} // HostToIp()
565
566
567//----------------------------------------------------------------------
568// class sFileIOUtils::RSyncFile()
569//----------------------------------------------------------------------
570int sFileIOUtils::RSyncFile(const std::string& source_host_name, const std::string& source_host_ip_address, const std::string& source_directory, const std::string& source_file_name, const std::string& target_directory, const std::string &optional_rsync_flags)
571{
572  std::stringstream rsync_command;
573  rsync_command << "rsync -av" << optional_rsync_flags << " ";
574  if (source_host_ip_address == "")
575  {
576    rsync_command << inet_ntoa(sFileIOUtils::HostToIp(source_host_name));
577  }
578  else
579  {
580    rsync_command << source_host_ip_address;
581  }
582  rsync_command << ":"
583                << source_directory
584                << source_file_name
585                << " "
586                << target_directory;
587
588  RRLIB_LOG_PRINT(USER, "executing <", rsync_command.str(), "> ...");
589  int ret = system(rsync_command.str().c_str());
590  RRLIB_LOG_PRINT(USER, " ... done.\n");
591
592  RRLIB_LOG_PRINT(ERROR, "finished with result ", ret);
593  return ret;
594} // RSyncFile()
595
596
597//----------------------------------------------------------------------
598// class sFileIOUtils::RSyncFiles()
599//----------------------------------------------------------------------
600int sFileIOUtils::RSyncFiles(const std::string& source_host_name, const std::string& source_host_ip_address, const std::string& source_directory, const std::vector<std::string>& source_file_names, const std::string& target_directory, const std::string &optional_rsync_flags)
601{
602  std::string file_list_file_name(target_directory + "sfileioutils_rsyncfiles.txt");
603  ofstream tmp_file_list(file_list_file_name.c_str());
604  std::ostream_iterator<std::string> tmp_file_list_iterator(tmp_file_list, "\n");
605  unique_copy(source_file_names.begin(), source_file_names.end(), tmp_file_list_iterator);
606  tmp_file_list.close();
607
608  std::stringstream rsync_command;
609  rsync_command << "rsync -avr" << optional_rsync_flags << " --files-from=" << file_list_file_name << " ";
610  if (source_host_ip_address == "")
611  {
612    rsync_command << inet_ntoa(sFileIOUtils::HostToIp(source_host_name));
613  }
614  else
615  {
616    rsync_command << source_host_ip_address;
617  }
618  rsync_command << ":"
619                << source_directory
620                << " "
621                << target_directory;
622
623  RRLIB_LOG_PRINT(USER, "executing <", rsync_command.str(), "> ...");
624  int ret = system(rsync_command.str().c_str());
625  RRLIB_LOG_PRINT(USER, "... done.\n");
626
627  RRLIB_LOG_PRINT(ERROR, "finished with result ", ret);
628  return ret;
629} // RSyncFiles()
630
631
632//----------------------------------------------------------------------
633// class sFileIOUtils::CheckAndGetFile()
634//----------------------------------------------------------------------
635bool sFileIOUtils::CheckAndGetFile(const std::string &file_name, std::string &full_local_file_name, const std::string& resource_repository, const std::string& resource_server, const std::string& local_resource_directory, const std::string& server_resource_directory, bool use_cache)
636{
637  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "started with local_resource_directory <", local_resource_directory, ">, resource_repository <", resource_repository, ">, file_name <", file_name, ">, resource_server <", resource_server, ">, server_resource_directory <", server_resource_directory, ">");
638
639  //!#####################################################################################################
640  //! step 0: check whether token "resource_repository + filename" is in local cache
641  //!         and thus file is *assumed* to have already been loaded since last clearing of cache
642  //!#####################################################################################################
643  std::map<std::string, std::string>::iterator resource_cache_entry;
644  if (use_cache && (resource_cache_entry = sFileIOUtils::resource_cache.find(resource_repository + file_name)) != sFileIOUtils::resource_cache.end())
645  {
646    full_local_file_name = resource_cache_entry->second;
647    return true;
648  }
649
650
651  //!#####################################################################################################
652  //! step 1: check whether file can be loaded from local host in local directory
653  //!         location of file is: "./ + resource_repository + filename"
654  //!         --> resource_repository is extracted from relative path within given scene description file
655  //!#####################################################################################################
656  full_local_file_name = "./" + resource_repository + file_name;
657
658  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "1. check: trying to load <", full_local_file_name, ">");
659  ifstream try_1(full_local_file_name.c_str());
660  if (try_1)
661  {
662    try_1.close();
663  }
664  else
665  {
666    //!#################################################################################################################
667    //! step 2: check whether file can be loaded from local host in given local_resource_directory
668    //!         location of file is: "local_resource_directory + resource_repository + filename"
669    //!         --> resource_repository is extracted from relative path within given scene description file
670    //!#################################################################################################################
671
672    // replace possible environment variables in local_resource_directory by corresponding values
673    std::string expanded_local_resource_directory;
674    if (!sFileIOUtils::ShellExpandFilename(expanded_local_resource_directory, local_resource_directory + "/"))
675    {
676      RRLIB_LOG_PRINT(ERROR, "Could not expand local resource directory!");
677      return false;
678    }
679    full_local_file_name = (expanded_local_resource_directory + resource_repository + file_name);
680
681    RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "2. check: trying to load <", full_local_file_name, ">");
682    ifstream try_2(full_local_file_name.c_str());
683    if (try_2)
684    {
685      try_2.close();
686    }
687    else
688    {
689      //!#################################################################################################################
690      //! step 3: check whether file can be loaded from resource server in given server_resource_directory
691      //!         location of file is: "server_resource_directory + resource_repository + filename"
692      //!#################################################################################################################
693
694      // get local host name
695      std::string local_host;
696      if (use_cache && sFileIOUtils::cached_local_host.length() > 0)
697      {
698        local_host = sFileIOUtils::cached_local_host;
699        RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "retrieved local_host <", local_host, "> from cache");
700      }
701      else
702      {
703        local_host = sFileIOUtils::cached_local_host = sFileIOUtils::GetHostName();
704      }
705
706      // get server ip address
707      std::string server(resource_server);
708      std::string server_ip_address;
709      if (server != "")
710      {
711        // retrieve ip address of optional resource server
712        std::map<std::string, std::string>::iterator pos;
713        if (use_cache && ((pos = sFileIOUtils::host_name_to_ip_cache.find(server)) != sFileIOUtils::host_name_to_ip_cache.end()))
714        {
715          server_ip_address = pos->second;
716          RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "retrieved ip address <", server_ip_address, "> of host <", server, "> from cache");
717        }
718        else
719        {
720          server_ip_address = inet_ntoa(sFileIOUtils::HostToIp(server));
721          RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "got ip address <", server_ip_address, "> of host <", server, ">");
722
723          if (server_ip_address == "0.0.0.0")
724          {
725            RRLIB_LOG_PRINT(ERROR, "zero ip address ... clearing server");
726            server = "";
727          }
728          else
729          {
730            sFileIOUtils::host_name_to_ip_cache[ server ] = server_ip_address;
731          }
732        }
733      }
734
735      // start check
736      if (server != "")   //&& server != local_host)
737      {
738        RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, "3. check: trying to rsync <", server_ip_address, ":", server_resource_directory + resource_repository + file_name, "> to <", expanded_local_resource_directory, ">");
739
740        // rsync from <resource_server:server_resource_directory + resource_repository>
741        //       to <local_resource_directory> on local host
742
743        if (sFileIOUtils::RSyncFile("", server_ip_address, server_resource_directory + "/./" + resource_repository, file_name, expanded_local_resource_directory, "R") != 0)
744        {
745          RRLIB_LOG_PRINT(ERROR, "could not rsync file <", file_name, "> from server <", server, "> at <", server_resource_directory + resource_repository, "> ... skipping");
746          return false;
747        }
748        full_local_file_name = (expanded_local_resource_directory + resource_repository + file_name);
749      }
750      else
751      {
752        RRLIB_LOG_PRINT(ERROR, "could neither load <", file_name, "> locally nor from resource server ... skipping");
753        return false;
754      }
755    }
756  }
757
758  //! ------------------------------- final check just to be sure that requested file is available --------------------
759  ifstream try_3(full_local_file_name.c_str());
760  if (!try_3)
761  {
762    RRLIB_LOG_PRINT(ERROR, "final check failed: could not load <", full_local_file_name, "> ... skipping");
763    return false;
764  }
765  else
766  {
767    try_3.close();
768  }
769  sFileIOUtils::resource_cache[ resource_repository + file_name ] = full_local_file_name;
770  return true;
771} // CheckAndGetFile()
772
773
774//----------------------------------------------------------------------
775// class sFileIOUtils::ClearCaches()
776//----------------------------------------------------------------------
777void sFileIOUtils::ClearCaches()
778{
779  sFileIOUtils::cached_local_host = "";
780  sFileIOUtils::host_name_to_ip_cache.clear();
781} // ClearCaches()
782
783
784//----------------------------------------------------------------------
785// class sFileIOUtils::ClearResourceCache()
786//----------------------------------------------------------------------
787void sFileIOUtils::ClearResourceCache()
788{
789  sFileIOUtils::resource_cache.clear();
790} // ClearResourceCache()
791
792//----------------------------------------------------------------------
793// End of namespace declaration
794//----------------------------------------------------------------------
795}
796}
Note: See TracBrowser for help on using the repository browser.