source: rrlib_util/sFileIOUtils.cpp @ 131:ff27859dca64

13.10
Last change on this file since 131:ff27859dca64 was 131:ff27859dca64, checked in by Bernd Helge Leroch <leroch@…>, 5 years ago

fixed issue in the context of name resolution

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