source: rrlib_util/sFileIOUtils.cpp @ 84:f328970a6b47

Last change on this file since 84:f328970a6b47 was 84:f328970a6b47, checked in by Tobias Föhst <foehst@…>, 7 years ago

Merged with changes from RRLab

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    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  assert(tokens.size() == 4);
465  RRLIB_LOG_PRINTF(USER, "found_name <%s> , ip <%s> \n", tokens[0].c_str(), tokens[3].c_str());
466
467  inet_aton(tokens[3].c_str(), &address);
468  return address;
469} // HostToIpViaHost()
470
471//----------------------------------------------------------------------
472// class sFileIOUtils::HostToIpViaHostsFile()
473//----------------------------------------------------------------------
474struct in_addr sFileIOUtils::HostToIpViaHostsFile(const std::string & name)
475{
476  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIpViaHostsFile() >>> started with host <%s>\n", name.c_str());
477  struct in_addr address;
478  address.s_addr = 0;
479
480  ifstream hosts_file("/etc/hosts");
481
482  char line[ 1024 ];
483  std::string line_str, ip_address;
484  std::vector<std::string> tokens;
485  bool found(false);
486  while (!hosts_file.eof() && !found)
487  {
488    hosts_file.getline(line, 1024);
489    line_str = std::string(line);
490    if (line_str.length() > 0 && line_str.find("#") == std::string::npos)
491    {
492      tokens.clear();
493      sStringUtils::Tokenize(line_str, tokens, " \t");
494
495      if (find(tokens.begin(), tokens.end(), name) != tokens.end())
496      {
497        for (std::vector<std::string>::const_iterator iter = tokens.begin(); iter != tokens.end(); ++iter)
498        {
499          if (inet_aton(iter->c_str(), &address))
500          {
501            ip_address = *iter;
502            RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIpViaHostsFile() >>> got ip <%s> of host <%s> from hosts file\n", ip_address.c_str(), name.c_str());
503            found = true;
504            break;
505          }
506        }
507      }
508    }
509  }
510  hosts_file.close();
511  return address;
512} // HostToIpViaHostsFile()
513
514
515//----------------------------------------------------------------------
516// class sFileIOUtils::HostToIp()
517//----------------------------------------------------------------------
518struct in_addr sFileIOUtils::HostToIp(const std::string & name)
519{
520  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIp() >>> started with host <%s>\n", name.c_str());
521
522  struct in_addr address;
523  address.s_addr = 0;
524
525  if ((address = sFileIOUtils::HostToIpViaHostsFile(name)).s_addr != 0)
526  {
527    RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIp() >>> got ip <%s> of host <%s> from hosts_file\n", inet_ntoa(address), name.c_str());
528  }
529  else if ((address = sFileIOUtils::HostToIpViaHost(name)).s_addr != 0)
530  {
531    RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIp() >>> got ip <%s> of host <%s> via <host -t A>\n", inet_ntoa(address), name.c_str());
532  }
533  else if ((address = sFileIOUtils::HostToIpViaNslookup(name)).s_addr != 0)
534  {
535    RRLIB_LOG_PRINTF(USER, "sFileIOUtils::HostToIp() >>> got ip <%s> of host <%s> via <nslookup>\n", inet_ntoa(address), name.c_str());
536  }
537  else
538  {
539    RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::HostToIp() >>> could not get ip of host <%s>\n", name.c_str());
540  }
541
542  return address;
543} // HostToIp()
544
545
546//----------------------------------------------------------------------
547// class sFileIOUtils::RSyncFile()
548//----------------------------------------------------------------------
549int 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)
550{
551  std::stringstream rsync_command;
552  rsync_command << "rsync -av" << optional_rsync_flags << " ";
553  if (source_host_ip_address == "")
554  {
555    rsync_command << inet_ntoa(sFileIOUtils::HostToIp(source_host_name));
556  }
557  else
558  {
559    rsync_command << source_host_ip_address;
560  }
561  rsync_command << ":"
562                << source_directory
563                << source_file_name
564                << " "
565                << target_directory;
566
567  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::RSyncFile() >>> executing <%s> ...\n", rsync_command.str().c_str());
568  int ret = system(rsync_command.str().c_str());
569  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::RSyncFile() >>> ... done.\n");
570
571  RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::RSyncFile() >>> finished with result %d\n", ret);
572  return ret;
573} // RSyncFile()
574
575
576//----------------------------------------------------------------------
577// class sFileIOUtils::RSyncFiles()
578//----------------------------------------------------------------------
579int 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)
580{
581  std::string file_list_file_name(target_directory + "sfileioutils_rsyncfiles.txt");
582  ofstream tmp_file_list(file_list_file_name.c_str());
583  std::ostream_iterator<std::string> tmp_file_list_iterator(tmp_file_list, "\n");
584  unique_copy(source_file_names.begin(), source_file_names.end(), tmp_file_list_iterator);
585  tmp_file_list.close();
586
587  std::stringstream rsync_command;
588  rsync_command << "rsync -avr" << optional_rsync_flags << " --files-from=" << file_list_file_name << " ";
589  if (source_host_ip_address == "")
590  {
591    rsync_command << inet_ntoa(sFileIOUtils::HostToIp(source_host_name));
592  }
593  else
594  {
595    rsync_command << source_host_ip_address;
596  }
597  rsync_command << ":"
598                << source_directory
599                << " "
600                << target_directory;
601
602  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::RSyncFiles() >>> executing <%s> ...\n", rsync_command.str().c_str());
603  int ret = system(rsync_command.str().c_str());
604  RRLIB_LOG_PRINTF(USER, "sFileIOUtils::RSyncFiles() >>> ... done.\n");
605
606  RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::RSyncFiles() >>> finished with result %d\n", ret);
607  return ret;
608} // RSyncFiles()
609
610
611//----------------------------------------------------------------------
612// class sFileIOUtils::CheckAndGetFile()
613//----------------------------------------------------------------------
614bool 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)
615{
616  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());
617
618  //!#####################################################################################################
619  //! step 0: check whether token "resource_repository + filename" is in local cache
620  //!         and thus file is *assumed* to have already been loaded since last clearing of cache
621  //!#####################################################################################################
622  std::map<std::string, std::string>::iterator resource_cache_entry;
623  if (use_cache && (resource_cache_entry = sFileIOUtils::resource_cache.find(resource_repository + file_name)) != sFileIOUtils::resource_cache.end())
624  {
625    full_local_file_name = resource_cache_entry->second;
626    return true;
627  }
628
629
630  //!#####################################################################################################
631  //! step 1: check whether file can be loaded from local host in local directory
632  //!         location of file is: "./ + resource_repository + filename"
633  //!         --> resource_repository is extracted from relative path within given scene description file
634  //!#####################################################################################################
635  full_local_file_name = "./" + resource_repository + file_name;
636
637  RRLIB_LOG_PRINTF(DEBUG_VERBOSE_1, "sFileIOUtils::CheckAndGetFile() >>> 1. check: trying to load <%s>\n", full_local_file_name.c_str());
638  ifstream try_1(full_local_file_name.c_str());
639  if (try_1)
640  {
641    try_1.close();
642  }
643  else
644  {
645    //!#################################################################################################################
646    //! step 2: check whether file can be loaded from local host in given local_resource_directory
647    //!         location of file is: "local_resource_directory + resource_repository + filename"
648    //!         --> resource_repository is extracted from relative path within given scene description file
649    //!#################################################################################################################
650
651    // replace possible environment variables in local_resource_directory by corresponding values
652    std::string expanded_local_resource_directory;
653    if (!sFileIOUtils::ShellExpandFilename(expanded_local_resource_directory, local_resource_directory + "/"))
654    {
655      RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::%s >> Could not expand local resource directory!\n", __FUNCTION__);
656      return false;
657    }
658    full_local_file_name = (expanded_local_resource_directory + resource_repository + file_name);
659
660    RRLIB_LOG_PRINTF(DEBUG_VERBOSE_1, "sFileIOUtils::CheckAndGetFile() >>> 2. check: trying to load <%s>\n", full_local_file_name.c_str());
661    ifstream try_2(full_local_file_name.c_str());
662    if (try_2)
663    {
664      try_2.close();
665    }
666    else
667    {
668      //!#################################################################################################################
669      //! step 3: check whether file can be loaded from resource server in given server_resource_directory
670      //!         location of file is: "server_resource_directory + resource_repository + filename"
671      //!#################################################################################################################
672
673      // get local host name
674      std::string local_host;
675      if (use_cache && sFileIOUtils::cached_local_host.length() > 0)
676      {
677        local_host = sFileIOUtils::cached_local_host;
678        RRLIB_LOG_PRINTF(DEBUG_VERBOSE_1, "sFileIOUtils::CheckAndGetFile() >>> retrieved local_host <%s> from cache\n", local_host.c_str());
679      }
680      else
681      {
682        local_host = sFileIOUtils::cached_local_host = sFileIOUtils::GetHostName();
683      }
684
685      // get server ip address
686      std::string server(resource_server);
687      std::string server_ip_address;
688      if (server != "")
689      {
690        // retrieve ip address of optional resource server
691        std::map<std::string, std::string>::iterator pos;
692        if (use_cache && ((pos = sFileIOUtils::host_name_to_ip_cache.find(server)) != sFileIOUtils::host_name_to_ip_cache.end()))
693        {
694          server_ip_address = pos->second;
695          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());
696        }
697        else
698        {
699          server_ip_address = inet_ntoa(sFileIOUtils::HostToIp(server));
700          RRLIB_LOG_PRINTF(DEBUG_VERBOSE_1, "sFileIOUtils::CheckAndGetFile() >>> got ip address <%s> of host <%s>\n", server_ip_address.c_str(), server.c_str());
701
702          if (server_ip_address == "0.0.0.0")
703          {
704            RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::constructor >>> zero ip address ... clearing server\n");
705            server = "";
706          }
707          else
708          {
709            sFileIOUtils::host_name_to_ip_cache[ server ] = server_ip_address;
710          }
711        }
712      }
713
714      // start check
715      if (server != "")   //&& server != local_host)
716      {
717        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());
718
719        // rsync from <resource_server:server_resource_directory + resource_repository>
720        //       to <local_resource_directory> on local host
721
722        if (sFileIOUtils::RSyncFile("", server_ip_address, server_resource_directory + "/./" + resource_repository, file_name, expanded_local_resource_directory, "R") != 0)
723        {
724          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());
725          return false;
726        }
727        full_local_file_name = (expanded_local_resource_directory + resource_repository + file_name);
728      }
729      else
730      {
731        RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::CheckAndGetFile() >>> could neither load <%s> locally nor from resource server ... skipping\n", file_name.c_str());
732        return false;
733      }
734    }
735  }
736
737  //! ------------------------------- final check just to be sure that requested file is available --------------------
738  ifstream try_3(full_local_file_name.c_str());
739  if (!try_3)
740  {
741    RRLIB_LOG_PRINTF(ERROR, "sFileIOUtils::CheckAndGetFile() >>> final check failed: could not load <%s> ... skipping\n", full_local_file_name.c_str());
742    return false;
743  }
744  else
745  {
746    try_3.close();
747  }
748  sFileIOUtils::resource_cache[ resource_repository + file_name ] = full_local_file_name;
749  return true;
750} // CheckAndGetFile()
751
752
753//----------------------------------------------------------------------
754// class sFileIOUtils::ClearCaches()
755//----------------------------------------------------------------------
756void sFileIOUtils::ClearCaches()
757{
758  sFileIOUtils::cached_local_host = "";
759  sFileIOUtils::host_name_to_ip_cache.clear();
760} // ClearCaches()
761
762
763//----------------------------------------------------------------------
764// class sFileIOUtils::ClearResourceCache()
765//----------------------------------------------------------------------
766void sFileIOUtils::ClearResourceCache()
767{
768  sFileIOUtils::resource_cache.clear();
769} // ClearResourceCache()
770
771//----------------------------------------------------------------------
772// End of namespace declaration
773//----------------------------------------------------------------------
774}
775}
Note: See TracBrowser for help on using the repository browser.