source: rrlib_util/sFileIOUtils.cpp @ 43:0b04f7b6406e

Last change on this file since 43:0b04f7b6406e was 43:0b04f7b6406e, checked in by Tobias Föhst <foehst@…>, 8 years ago

Reformatted with astyle 2.02.1

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