source: rrlib_util/sFileIOUtils.cpp @ 12:a3f5a59a5227

Last change on this file since 12:a3f5a59a5227 was 12:a3f5a59a5227, checked in by Jens Wettach <wettach@…>, 9 years ago

adjusted debug output

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