source: rrlib_util/sFileIOUtils.cpp @ 83:10f32063cdf7

Last change on this file since 83:10f32063cdf7 was 83:10f32063cdf7, checked in by Patrick Fleischmann <fleischmann@…>, 7 years ago

Method added to test if a file exists

File size: 28.8 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(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(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(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(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(ERROR, "sFileIOUtils>> Execution of command '%s' failed!\n", cmd.str().c_str());
200    exit(EXIT_FAILURE);
201  }
202} // DecompressFile()
203
204//----------------------------------------------------------------------
205// class sFileIOUtils::FileExists()
206//----------------------------------------------------------------------
207bool sFileIOUtils::FileExists(const std::string &filename)
208{
209  // catch empty file
210  if (filename == "")
211  {
212    return false;
213  }
214
215  // test if file exists
216  FILE* file = fopen(filename.c_str(), "rb");
217  if (file == 0)
218  {
219    return false;
220  }
221  fclose(file);
222
223  return true;
224}
225
226
227//----------------------------------------------------------------------
228// class sFileIOUtils::ShellExpandFilename()
229//----------------------------------------------------------------------
230bool sFileIOUtils::ShellExpandFilename(std::string &file_name)
231{
232  return ShellExpandFilename(file_name, file_name);
233} // ShellExpandFilename()
234
235//----------------------------------------------------------------------
236// class sFileIOUtils::ShellExpandFilename()
237//----------------------------------------------------------------------
238bool sFileIOUtils::ShellExpandFilename(std::string &result, const std::string &file_name)
239{
240  //result = "";  //in case &result == &file_name, then it causes trouble.
241  wordexp_t expansion;
242  int error = wordexp(file_name.c_str(), &expansion, WRDE_SHOWERR | WRDE_UNDEF);
243  if (error)
244  {
245    const char *error_msg = 0;
246    switch (error)
247    {
248    case WRDE_BADCHAR:
249      error_msg = "Illegal occurrence of newline or one of |, &, ;, <, >, (, ), {, }";
250      break;
251    case WRDE_BADVAL:
252      error_msg = "An undefined shell variable was referenced";
253      break;
254    case WRDE_NOSPACE:
255      error_msg = "Out of memory";
256      break;
257    case WRDE_SYNTAX:
258      error_msg = "Shell syntax error, such as unbalanced parentheses or unmatched quotes";
259      break;
260    default:
261      error_msg = "Unknown error";
262    }
263    RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::%s >> Could not expand '%s': %s!\n", __FUNCTION__, file_name.c_str(), error_msg);
264    return false;
265  }
266
267  std::stringstream stream;
268  stream << util::Join(expansion.we_wordv + expansion.we_offs, expansion.we_wordv + expansion.we_offs + expansion.we_wordc, " ");
269  wordfree(&expansion);
270
271  result = stream.str();
272
273  return true;
274} // ShellExpandFilename()
275
276//----------------------------------------------------------------------
277// class sFileIOUtils::SplitFullQualifiedFilename()
278//----------------------------------------------------------------------
279void sFileIOUtils::SplitFullQualifiedFilename(const std::string& complete_name, std::string& file_dir, std::string& file_base, std::string& file_ext)
280{
281
282  std::string::size_type pos_slash = complete_name.find_last_of("/");
283  std::string::size_type pos_name = pos_slash + 1;
284
285  if (pos_slash == std::string::npos)
286  {
287    // no slash found
288    file_dir = "./";
289    pos_name = 0;
290    pos_slash = 0;
291  }
292  else
293  {
294    file_dir = complete_name.substr(0, pos_slash);
295  }
296
297  //    cerr << "pos_slash: " << pos_slash << endl;
298  std::string::size_type pos_dot = complete_name.find_last_of(".");
299  if (pos_dot == std::string::npos || pos_dot < pos_slash)
300  {
301    // no dot found or dot in directory
302    file_base = complete_name.substr(pos_name);
303    file_ext = "";
304  }
305  else
306  {
307    file_base = complete_name.substr(pos_name, pos_dot - pos_name);
308    file_ext = complete_name.substr(pos_dot);
309  }
310
311} // SplitFullQualifiedFilename()
312
313
314
315//----------------------------------------------------------------------
316// class sFileIOUtils::GetHostName()
317//----------------------------------------------------------------------
318std::string sFileIOUtils::GetHostName(bool fqdn)
319{
320  //RRLIB_LOG_PRINTF(USER, "sFileIOUtils::GetHostName() >>> started\n");
321  std::string cmd = fqdn ? "hostname -f" : "hostname";
322  FILE * pipe = popen(cmd.c_str(), "r");
323  char buf[ 1024 ];
324  if (fgets(buf, sizeof(buf), pipe) == 0)
325  {
326    RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::GetHostName(bool fqdn) >> Error querying host name!\n");
327    exit(EXIT_FAILURE);
328  }
329  pclose(pipe);
330  std::string name(buf);
331  sStringUtils::TrimWhitespace(name);
332  //boost::trim(name);
333  //RRLIB_LOG_PRINTF(USER, "sFileIOUtils::GetHostName() >>> finished with name <%s>\n", name.c_str());
334  return name;
335} // GetHostName()
336
337//----------------------------------------------------------------------
338// class sFileIOUtils::HostToIpViaGetHostByName()
339//----------------------------------------------------------------------
340struct ::in_addr sFileIOUtils::HostToIpViaGetHostByName(const std::string& name)
341{
342  struct in_addr address;
343  address.s_addr = 0;
344  struct hostent *host_ent = gethostbyname(name.c_str());       //alternative (from kernel/tTCPSocket): GetHostByName( name );
345  if (host_ent)
346  {
347    address = * ((struct in_addr *) host_ent->h_addr_list[ 0 ]);
348    RRLIB_LOG_PRINTF(USER, "ip address of host <%s> = <%s>\n", name.c_str(), inet_ntoa(address));
349  }
350  else
351  {
352    RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::GetIpAddressOfHost() >>> could not get ip address of host <%s>\n", name.c_str());
353  }
354  return address;
355} //HostToIpViaGetHostByName()
356
357
358//----------------------------------------------------------------------
359// class sFileIOUtils::HostToIpViaNslookup()
360//----------------------------------------------------------------------
361struct in_addr sFileIOUtils::HostToIpViaNslookup(const std::string & name)
362{
363  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIpViaNslookup() >>> started with host <%s>\n", name.c_str());
364  struct in_addr address;
365  address.s_addr = 0;
366
367  std::stringstream command;
368  command << "nslookup \"" << name << "\"";
369  RRLIB_LOG_PRINTF(USER, "command = <%s>\n", command.str().c_str());
370  FILE * pipe = popen(command.str().c_str(), "r");
371  if (!pipe)
372  {
373    perror("error\n");
374    return address;
375  }
376  std::stringstream result;
377  char buf[ 512 ];
378  while (fgets(buf, 512, pipe) != NULL)
379  {
380    result << buf;
381  }
382  pclose(pipe);
383  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIpViaNslookup() >>> host = <%s> , result = <%s> \n", name.c_str(), result.str().c_str());
384
385  std::string result_str(result.str());
386  std::string search_token("Name:");
387  std::string::size_type pos = result_str.find(search_token);
388  if (pos == std::string::npos)
389  {
390    RRLIB_LOG_PRINTF(ERROR, "Could not find token <%s> in nslookup result ... returning <%s> \n", search_token.c_str(), inet_ntoa(address));
391    return address;
392  }
393  result_str.erase(0, pos + search_token.length());
394  RRLIB_LOG_PRINTF(USER, "pos = %zd\n", pos);
395
396  search_token = "Address:";
397  pos = result_str.find(search_token);
398  if (pos == std::string::npos)
399  {
400    RRLIB_LOG_PRINTF(ERROR, "Could not find token <%s> in nslookup result ... returning <%s> \n", search_token.c_str(), inet_ntoa(address));
401    return address;
402  }
403  RRLIB_LOG_PRINTF(USER, "pos = %zd\n", pos);
404
405  std::string found_name(result_str.substr(0, pos));
406  sStringUtils::TrimWhitespace(found_name);
407  //boost::trim(found_name);
408  std::string ip(result_str.substr(pos + search_token.length()));
409  sStringUtils::TrimWhitespace(ip);
410  //boost::trim(ip);
411
412  RRLIB_LOG_PRINTF(USER, "found_name <%s> , name <%s> \n", found_name.c_str(), name.c_str());
413
414  if (found_name != name)
415  {
416    RRLIB_LOG_PRINTF(ERROR, "nslookup failed .... returning <%s> \n", inet_ntoa(address));
417    return address;
418  }
419  RRLIB_LOG_PRINTF(USER, "found_name <%s> , ip <%s> \n", found_name.c_str(), ip.c_str());
420
421  inet_aton(ip.c_str(), &address);
422
423  //return ip.c_str();
424  return address;
425} // HostToIpViaNslookup()
426
427
428//----------------------------------------------------------------------
429// class sFileIOUtils::HostToIpViaHost()
430//----------------------------------------------------------------------
431struct in_addr sFileIOUtils::HostToIpViaHost(const std::string & name)
432{
433  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIpViaHost() >>> started with host <%s>\n", name.c_str());
434  struct in_addr address;
435  address.s_addr = 0;
436
437  std::stringstream command;
438  command << "host -t A \"" << name << "\"";
439  RRLIB_LOG_PRINTF(USER, "command = <%s>\n", command.str().c_str());
440  FILE * pipe = popen(command.str().c_str(), "r");
441  if (!pipe)
442  {
443    perror("error\n");
444    return address;
445  }
446  std::stringstream result;
447  char buf[ 512 ];
448  while (fgets(buf, 512, pipe) != NULL)
449  {
450    result << buf;
451  }
452  pclose(pipe);
453  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIpViaHost() >>> host = <%s> , result = <%s> \n", name.c_str(), result.str().c_str());
454
455  std::string result_str(result.str());
456  std::vector<std::string> tokens;
457  sStringUtils::Tokenize(result_str, tokens, " \t");
458
459  for_each(tokens.begin(), tokens.end(), sStringUtils::Trim<std::string>());
460  RRLIB_LOG_PRINTF(DEBUG_VERBOSE_1, "sFileIOUtils::HostToIpViaHost() >>> got %d tokens:\n", tokens.size());
461  RRLIB_LOG_PRINT(DEBUG_VERBOSE_1, Join(tokens, "\n"));
462
463  assert(tokens.size() == 4);
464  RRLIB_LOG_PRINTF(USER, "found_name <%s> , ip <%s> \n", tokens[0].c_str(), tokens[3].c_str());
465
466  inet_aton(tokens[3].c_str(), &address);
467  return address;
468} // HostToIpViaHost()
469
470//----------------------------------------------------------------------
471// class sFileIOUtils::HostToIpViaHostsFile()
472//----------------------------------------------------------------------
473struct in_addr sFileIOUtils::HostToIpViaHostsFile(const std::string & name)
474{
475  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIpViaHostsFile() >>> started with host <%s>\n", name.c_str());
476  struct in_addr address;
477  address.s_addr = 0;
478
479  ifstream hosts_file("/etc/hosts");
480
481  char line[ 1024 ];
482  std::string line_str, ip_address;
483  std::vector<std::string> tokens;
484  bool found(false);
485  while (!hosts_file.eof() && !found)
486  {
487    hosts_file.getline(line, 1024);
488    line_str = std::string(line);
489    if (line_str.length() > 0 && line_str.find("#") == std::string::npos)
490    {
491      tokens.clear();
492      sStringUtils::Tokenize(line_str, tokens, " \t");
493
494      if (find(tokens.begin(), tokens.end(), name) != tokens.end())
495      {
496        for (std::vector<std::string>::const_iterator iter = tokens.begin(); iter != tokens.end(); ++iter)
497        {
498          if (inet_aton(iter->c_str(), &address))
499          {
500            ip_address = *iter;
501            RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIpViaHostsFile() >>> got ip <%s> of host <%s> from hosts file\n", ip_address.c_str(), name.c_str());
502            found = true;
503            break;
504          }
505        }
506      }
507    }
508  }
509  hosts_file.close();
510  return address;
511} // HostToIpViaHostsFile()
512
513
514//----------------------------------------------------------------------
515// class sFileIOUtils::HostToIp()
516//----------------------------------------------------------------------
517struct in_addr sFileIOUtils::HostToIp(const std::string & name)
518{
519  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIp() >>> started with host <%s>\n", name.c_str());
520
521  struct in_addr address;
522  address.s_addr = 0;
523
524  if ((address = sFileIOUtils::HostToIpViaHostsFile(name)).s_addr != 0)
525  {
526    RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIp() >>> got ip <%s> of host <%s> from hosts_file\n", inet_ntoa(address), name.c_str());
527  }
528  else if ((address = sFileIOUtils::HostToIpViaHost(name)).s_addr != 0)
529  {
530    RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIp() >>> got ip <%s> of host <%s> via <host -t A>\n", inet_ntoa(address), name.c_str());
531  }
532  else if ((address = sFileIOUtils::HostToIpViaNslookup(name)).s_addr != 0)
533  {
534    RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIp() >>> got ip <%s> of host <%s> via <nslookup>\n", inet_ntoa(address), name.c_str());
535  }
536  else
537  {
538    RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::HostToIp() >>> could not get ip of host <%s>\n", name.c_str());
539  }
540
541  return address;
542} // HostToIp()
543
544
545//----------------------------------------------------------------------
546// class sFileIOUtils::RSyncFile()
547//----------------------------------------------------------------------
548int 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)
549{
550  std::stringstream rsync_command;
551  rsync_command << "rsync -av" << optional_rsync_flags << " ";
552  if (source_host_ip_address == "")
553  {
554    rsync_command << inet_ntoa(sFileIOUtils::HostToIp(source_host_name));
555  }
556  else
557  {
558    rsync_command << source_host_ip_address;
559  }
560  rsync_command << ":"
561                << source_directory
562                << source_file_name
563                << " "
564                << target_directory;
565
566  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::RSyncFile() >>> executing <%s> ...\n", rsync_command.str().c_str());
567  int ret = system(rsync_command.str().c_str());
568  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::RSyncFile() >>> ... done.\n");
569
570  RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::RSyncFile() >>> finished with result %d\n", ret);
571  return ret;
572} // RSyncFile()
573
574
575//----------------------------------------------------------------------
576// class sFileIOUtils::RSyncFiles()
577//----------------------------------------------------------------------
578int 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)
579{
580  std::string file_list_file_name(target_directory + "sfileioutils_rsyncfiles.txt");
581  ofstream tmp_file_list(file_list_file_name.c_str());
582  std::ostream_iterator<std::string> tmp_file_list_iterator(tmp_file_list, "\n");
583  unique_copy(source_file_names.begin(), source_file_names.end(), tmp_file_list_iterator);
584  tmp_file_list.close();
585
586  std::stringstream rsync_command;
587  rsync_command << "rsync -avr" << optional_rsync_flags << " --files-from=" << file_list_file_name << " ";
588  if (source_host_ip_address == "")
589  {
590    rsync_command << inet_ntoa(sFileIOUtils::HostToIp(source_host_name));
591  }
592  else
593  {
594    rsync_command << source_host_ip_address;
595  }
596  rsync_command << ":"
597                << source_directory
598                << " "
599                << target_directory;
600
601  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::RSyncFiles() >>> executing <%s> ...\n", rsync_command.str().c_str());
602  int ret = system(rsync_command.str().c_str());
603  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::RSyncFiles() >>> ... done.\n");
604
605  RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::RSyncFiles() >>> finished with result %d\n", ret);
606  return ret;
607} // RSyncFiles()
608
609
610//----------------------------------------------------------------------
611// class sFileIOUtils::CheckAndGetFile()
612//----------------------------------------------------------------------
613bool 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)
614{
615  RRLIB_LOG_PRINTF(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());
616
617  //!#####################################################################################################
618  //! step 0: check whether token "resource_repository + filename" is in local cache
619  //!         and thus file is *assumed* to have already been loaded since last clearing of cache
620  //!#####################################################################################################
621  std::map<std::string, std::string>::iterator resource_cache_entry;
622  if (use_cache && (resource_cache_entry = sFileIOUtils::resource_cache.find(resource_repository + file_name)) != sFileIOUtils::resource_cache.end())
623  {
624    full_local_file_name = resource_cache_entry->second;
625    return true;
626  }
627
628
629  //!#####################################################################################################
630  //! step 1: check whether file can be loaded from local host in local directory
631  //!         location of file is: "./ + resource_repository + filename"
632  //!         --> resource_repository is extracted from relative path within given scene description file
633  //!#####################################################################################################
634  full_local_file_name = "./" + resource_repository + file_name;
635
636  RRLIB_LOG_PRINTF(DEBUG_VERBOSE_1, "sFileIOUtils::CheckAndGetFile() >>> 1. check: trying to load <%s>\n", full_local_file_name.c_str());
637  ifstream try_1(full_local_file_name.c_str());
638  if (try_1)
639  {
640    try_1.close();
641  }
642  else
643  {
644    //!#################################################################################################################
645    //! step 2: check whether file can be loaded from local host in given local_resource_directory
646    //!         location of file is: "local_resource_directory + resource_repository + filename"
647    //!         --> resource_repository is extracted from relative path within given scene description file
648    //!#################################################################################################################
649
650    // replace possible environment variables in local_resource_directory by corresponding values
651    std::string expanded_local_resource_directory;
652    if (!sFileIOUtils::ShellExpandFilename(expanded_local_resource_directory, local_resource_directory + "/"))
653    {
654      RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::%s >> Could not expand local resource directory!\n", __FUNCTION__);
655      return false;
656    }
657    full_local_file_name = (expanded_local_resource_directory + resource_repository + file_name);
658
659    RRLIB_LOG_PRINTF(DEBUG_VERBOSE_1, "sFileIOUtils::CheckAndGetFile() >>> 2. check: trying to load <%s>\n", full_local_file_name.c_str());
660    ifstream try_2(full_local_file_name.c_str());
661    if (try_2)
662    {
663      try_2.close();
664    }
665    else
666    {
667      //!#################################################################################################################
668      //! step 3: check whether file can be loaded from resource server in given server_resource_directory
669      //!         location of file is: "server_resource_directory + resource_repository + filename"
670      //!#################################################################################################################
671
672      // get local host name
673      std::string local_host;
674      if (use_cache && sFileIOUtils::cached_local_host.length() > 0)
675      {
676        local_host = sFileIOUtils::cached_local_host;
677        RRLIB_LOG_PRINTF(DEBUG_VERBOSE_1, "sFileIOUtils::CheckAndGetFile() >>> retrieved local_host <%s> from cache\n", local_host.c_str());
678      }
679      else
680      {
681        local_host = sFileIOUtils::cached_local_host = sFileIOUtils::GetHostName();
682      }
683
684      // get server ip address
685      std::string server(resource_server);
686      std::string server_ip_address;
687      if (server != "")
688      {
689        // retrieve ip address of optional resource server
690        std::map<std::string, std::string>::iterator pos;
691        if (use_cache && ((pos = sFileIOUtils::host_name_to_ip_cache.find(server)) != sFileIOUtils::host_name_to_ip_cache.end()))
692        {
693          server_ip_address = pos->second;
694          RRLIB_LOG_PRINTF(DEBUG_VERBOSE_1, "sFileIOUtils::CheckAndGetFile() >>> retrieved ip address <%s> of host <%s> from cache\n", server_ip_address.c_str(), server.c_str());
695        }
696        else
697        {
698          server_ip_address = inet_ntoa(sFileIOUtils::HostToIp(server));
699          RRLIB_LOG_PRINTF(DEBUG_VERBOSE_1, "sFileIOUtils::CheckAndGetFile() >>> got ip address <%s> of host <%s>\n", server_ip_address.c_str(), server.c_str());
700
701          if (server_ip_address == "0.0.0.0")
702          {
703            RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::constructor >>> zero ip address ... clearing server\n");
704            server = "";
705          }
706          else
707          {
708            sFileIOUtils::host_name_to_ip_cache[ server ] = server_ip_address;
709          }
710        }
711      }
712
713      // start check
714      if (server != "")   //&& server != local_host)
715      {
716        RRLIB_LOG_PRINTF(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());
717
718        // rsync from <resource_server:server_resource_directory + resource_repository>
719        //       to <local_resource_directory> on local host
720
721        if (sFileIOUtils::RSyncFile("", server_ip_address, server_resource_directory + "/./" + resource_repository, file_name, expanded_local_resource_directory, "R") != 0)
722        {
723          RRLIB_LOG_PRINTF(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());
724          return false;
725        }
726        full_local_file_name = (expanded_local_resource_directory + resource_repository + file_name);
727      }
728      else
729      {
730        RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::CheckAndGetFile() >>> could neither load <%s> locally nor from resource server ... skipping\n", file_name.c_str());
731        return false;
732      }
733    }
734  }
735
736  //! ------------------------------- final check just to be sure that requested file is available --------------------
737  ifstream try_3(full_local_file_name.c_str());
738  if (!try_3)
739  {
740    RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::CheckAndGetFile() >>> final check failed: could not load <%s> ... skipping\n", full_local_file_name.c_str());
741    return false;
742  }
743  else
744  {
745    try_3.close();
746  }
747  sFileIOUtils::resource_cache[ resource_repository + file_name ] = full_local_file_name;
748  return true;
749} // CheckAndGetFile()
750
751
752//----------------------------------------------------------------------
753// class sFileIOUtils::ClearCaches()
754//----------------------------------------------------------------------
755void sFileIOUtils::ClearCaches()
756{
757  sFileIOUtils::cached_local_host = "";
758  sFileIOUtils::host_name_to_ip_cache.clear();
759} // ClearCaches()
760
761
762//----------------------------------------------------------------------
763// class sFileIOUtils::ClearResourceCache()
764//----------------------------------------------------------------------
765void sFileIOUtils::ClearResourceCache()
766{
767  sFileIOUtils::resource_cache.clear();
768} // ClearResourceCache()
769
770//----------------------------------------------------------------------
771// End of namespace declaration
772//----------------------------------------------------------------------
773}
774}
Note: See TracBrowser for help on using the repository browser.