root/ossiedev/branches/jsnyder/trunk/system/ossie/framework/FileSystem_impl.cpp @ 11064

Revision 11064, 15.0 KB (checked in by Snyder.Jason, 2 years ago)

committing patches from opencpi

  • Property svn:eol-style set to native
Line 
1/****************************************************************************
2
3Copyright 2004, 2007, Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE Core Framework.
6
7OSSIE Core Framework is free software; you can redistribute it and/or modify
8it under the terms of the Lesser GNU General Public License as published by
9the Free Software Foundation; either version 2.1 of the License, or
10(at your option) any later version.
11
12OSSIE Core Framework is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15Lesser GNU General Public License for more details.
16
17You should have received a copy of the Lesser GNU General Public License
18along with OSSIE Core Framework; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21****************************************************************************/
22
23#include <string>
24#include "ossie/FileSystem_impl.h"
25
26#ifdef USE_OPENCPI_FS
27#include "OcpiUtilFileFs.h"
28#include "OcpiCFUtilVfsFileSystem.h"
29
30
31FileSystem_impl::FileSystem_impl()
32: OCPI::CFUtil::VfsFileSystem(ossieSupport::ORB::poa,
33                              new OCPI::Util::FileFs::FileFs())
34{
35}
36FileSystem_impl::FileSystem_impl(const char *root)
37: OCPI::CFUtil::VfsFileSystem(ossieSupport::ORB::poa,
38                              new OCPI::Util::FileFs::FileFs(root))
39{
40}
41
42FileSystem_impl::~FileSystem_impl(){}
43
44// static
45bool FileSystem_impl::isValidPath(const char *path) {
46  try {
47    std::string s(path);
48    testFileName(s);
49  } catch (...) {
50    return false;
51  }
52  return true;
53}
54
55// static
56void FileSystem_impl::joinPath(const char *base, const char *rel, std::string &result) {
57  result = OCPI::Util::Vfs::joinNames(OCPI::Util::Vfs::directoryName(base), rel);
58}
59
60#else
61/* SCA */
62
63#include <iostream>
64#include <fnmatch.h>
65
66#include <boost/filesystem/operations.hpp>
67#include <boost/filesystem/path.hpp>
68#include <boost/filesystem/exception.hpp>
69#ifndef BOOST_VERSION
70#include <boost/version.hpp>
71#endif
72
73#if BOOST_VERSION < 103500
74#  include <boost/filesystem/cerrno.hpp>
75#else
76#  include <boost/cerrno.hpp>
77#endif
78
79namespace fs = boost::filesystem;
80
81#include "ossie/debug.h"
82
83FileSystem_impl::FileSystem_impl ()
84{
85    DEBUG(6, FileSystem, "In constructor.");
86
87    root = fs::initial_path();
88
89    init ();
90}
91
92
93FileSystem_impl::FileSystem_impl (const char *_root)
94{
95    DEBUG(6, FileSystem, "In constructor with " << _root);
96
97    root = _root;
98
99    init ();
100}
101
102
103void
104FileSystem_impl::init ()
105{
106    DEBUG(6, FileSystem, "In init()");
107}
108
109FileSystem_impl::~FileSystem_impl ()
110{
111    DEBUG(6, FileSystem, "In destructor.");
112}
113
114// Filename utility functions as static member functions of FileSystem_impl,
115// implemented using boost here, to limit boost dependency to here
116// static
117bool FileSystem_impl::isValidPath(const char *fileName) {
118    try {
119        fs::path testPath(fileName);
120    } catch (...) {
121        return false;
122    }
123
124    return true;
125}
126// static
127void FileSystem_impl::joinPath(const char *spdFile, const char *name, std::string &fileName) {
128    fs::path spdPath(spdFile);
129
130    fs::path filePath = spdPath.branch_path() / name;
131
132    fileName = filePath.string();
133}
134
135
136void FileSystem_impl::remove (const char *fileName) throw (CORBA::SystemException, CF::FileException, CF::InvalidFileName)
137{
138    DEBUG(6, FileSystem, "In remove with " << fileName);
139
140    if (!ossieSupport::isValidFileName(fileName)) {
141        DEBUG(7, FileSystem, "remove passed bad filename, throwing exception.");
142        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::remove] Invalid file name");
143    }
144
145    fs::path fname(root / fileName);
146
147    DEBUG(6, FileSystem, "About to remove file " << fname.string());
148    bool exists = fs::remove(fname);
149
150    if (!exists) {
151        DEBUG(6, FileSystem, "Attempt to remove non-existant file.");
152        throw (CF::FileException (CF::CFEEXIST, "[FileSystem_impl::remove] Error removing file from file system"));
153    }
154}
155
156void FileSystem_impl::copy (const char *sourceFileName, const char *destinationFileName) throw (CORBA::SystemException, CF::InvalidFileName, CF::FileException)
157{
158    DEBUG(6, FileSystem, "In copy from " << sourceFileName << " to " << destinationFileName);
159
160    if (sourceFileName[0] != '/' || destinationFileName[0] != '/' || !ossieSupport::isValidFileName(sourceFileName) || !ossieSupport::isValidFileName(destinationFileName)) {
161        DEBUG(7, FileSystem, "copy passed bad filename, throwing exception.");
162        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::copy] Invalid file name");
163    }
164
165    try {
166        fs::path sFile(root / sourceFileName);
167        fs::path dFile(root / destinationFileName);
168
169        if (fs::is_directory(sFile))
170            return;
171
172        fs::copy_file(sFile, dFile);
173    } catch (const fs::filesystem_error &ex) {
174#if BOOST_VERSION < 103400
175        if (ex.error() == fs::not_found_error)
176#elif BOOST_VERSION < 103500
177        if (ex.system_error() == ENOENT)
178#else
179        if (ex.code().value() == ENOENT)
180#endif
181            throw CF::FileException(CF::CFENOENT, ex.what());
182    }
183}
184
185CORBA::Boolean FileSystem_impl::exists (const char *fileName)
186throw (CORBA::SystemException, CF::InvalidFileName)
187{
188    DEBUG(6, FileSystem, "In exists with " << fileName);
189
190    if (fileName[0] != '/' || !ossieSupport::isValidFileName(fileName)) {
191        DEBUG(7, FileSystem, "exists passed bad filename, throwing exception.");
192        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::exists] Invalid file name");
193    }
194
195    fs::path fname(root / fileName);
196
197    DEBUG(9, FileSystem, "Check for file " << fname.string());
198
199    return(fs::exists(fname));
200}
201
202void FileSystem_impl::recursiveList(const fs::path& dirPath, const char* pattern, CF::FileSystem::FileInformationSequence_var& fis)
203{
204    DEBUG(4, FileSystem, "Entering recursiveList")
205
206    try {
207        fs::path filePath(pattern);
208        std::string searchPattern(filePath.string());
209        unsigned int idx = fis->length();
210        DEBUG(4, FileSystem, "In list with path " << dirPath.string() << ", and pattern " << searchPattern);
211        fs::directory_iterator end_itr; // past the end
212        for (fs::directory_iterator itr(dirPath); itr != end_itr; ++itr) {
213            if (fs::is_directory(*itr)) recursiveList(*itr, pattern, fis);
214            DEBUG(9, FileSystem, "In list checking file " << itr->path().filename());
215            if (fnmatch(searchPattern.c_str(), itr->path().filename().c_str(), 0) == 0) {
216                DEBUG(9, FileSystem, "Match in list with " << itr->path().string());
217                fis->length(idx + 1);
218
219                if (fs::is_directory(*itr)) {
220                    std::string tmp(itr->path().string());
221                    tmp += "/";
222                    fis[idx].name = CORBA::string_dup(tmp.c_str());
223                    fis[idx].kind = CF::FileSystem::DIRECTORY;
224                    fis[idx].size = 0;
225                } else {
226                    std::string full_path = dirPath.string();
227                    full_path += "/";
228                    full_path += itr->path().string();
229                    fis[idx].name = CORBA::string_dup(full_path.c_str());
230                    fis[idx].kind = CF::FileSystem::PLAIN;
231                    fis[idx].size = fs::file_size(*itr);
232                }
233                /// \todo fix file creation time and last access time
234                CF::Properties prop;
235                prop.length(3);
236                prop[0].id = CORBA::string_dup(CF::FileSystem::CREATED_TIME_ID);
237                prop[0].value <<= fs::last_write_time(*itr);
238                prop[1].id = CORBA::string_dup(CF::FileSystem::MODIFIED_TIME_ID);
239                prop[1].value <<= fs::last_write_time(*itr);
240                prop[2].id = CORBA::string_dup(CF::FileSystem::LAST_ACCESS_TIME_ID);
241                prop[2].value <<= fs::last_write_time(*itr);
242                fis[idx].fileProperties = prop;
243                ++idx;
244            }
245        }
246        DEBUG(4, FileSystem, "About to return from list.");
247    } catch (const fs::filesystem_error &ex) {
248#if BOOST_VERSION < 103400
249        DEBUG(9, FileSystem, "Caught exception in list, error_code " << ex.error());
250        if (ex.error() == fs::other_error)
251#elif BOOST_VERSION < 103500
252        DEBUG(9, FileSystem, "Caught exception in list, error_code " << ex.system_error());
253        if (ex.system_error() == EINVAL)
254#else
255        DEBUG(9, FileSystem, "Caught exception in list, error_code " << ex.code().value());
256        if (ex.code().value() == EINVAL)
257#endif
258            throw CF::InvalidFileName(CF::CFEINVAL, ex.what());
259        throw CF::FileException(CF::CFNOTSET, ex.what());
260    }
261    DEBUG(4, FileSystem, "Leaving recursiveList")
262}
263
264/// \todo: modify to search the pattern as a regular expression
265CF::FileSystem::FileInformationSequence* FileSystem_impl::list (const char *pattern) throw (CORBA::SystemException, CF::FileException, CF::InvalidFileName)
266{
267    DEBUG(6, FileSystem, "In list with " << pattern);
268
269    const fs::path rootDirPath(root);
270    CF::FileSystem::FileInformationSequence_var result = new CF::FileSystem::FileInformationSequence;
271    result->length(0);
272
273    try {
274      recursiveList(rootDirPath, pattern, result);
275    } catch (const fs::filesystem_error &ex) {
276      // Convert boost fs errors into SCA FileSystem errors
277#if BOOST_VERSION < 103400
278      DEBUG(9, FileManager, "Caught exception in list, error_code " << ex.error());
279      if (ex.error() == fs::other_error)
280#elif BOOST_VERSION < 103500
281      DEBUG(9, FileManager, "Caught exception in list, error_code " << ex.system_error());
282      if (ex.system_error() == EINVAL)
283#else
284      DEBUG(9, FileManager, "Caught exception in list, error_code " << ex.code().value()); ;
285      if (ex.code().value() == EINVAL)
286#endif
287        throw CF::InvalidFileName(CF::CFEINVAL, ex.what());
288      throw CF::FileException(CF::CFNOTSET, ex.what());
289    }
290    return result._retn();
291}
292
293
294CF::File_ptr FileSystem_impl::create (const char *fileName) throw (CORBA::SystemException, CF::InvalidFileName, CF::FileException)
295{
296    DEBUG(6, FileSystem, "In create with " << fileName);
297
298    if (!ossieSupport::isValidFileName(fileName)) {
299        DEBUG(7, FileSystem, "create passed bad filename, throwing exception.");
300        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::create] Invalid file name");
301    }
302
303    if (exists(fileName)) {
304        DEBUG(6, FileSystem, "FileName exists in create, throwing exception.");
305        throw CF::FileException(CF::CFEEXIST, "File exists.");
306    }
307
308    File_impl *file = new File_impl (fileName, root, false, true);
309    CF::File_var fileServant = file->_this();
310
311    fileInfo newFile;
312    newFile.fileName = fileName;
313    newFile.servant = fileServant;
314    files.push_back(newFile);
315
316    return fileServant._retn();
317}
318
319CF::File_ptr FileSystem_impl::open (const char *fileName, CORBA::Boolean read_Only) throw (CORBA::SystemException, CF::InvalidFileName, CF::FileException)
320{
321    DEBUG(6, FileSystem, "In open with " << fileName);
322
323    if (!ossieSupport::isValidFileName(fileName)) {
324        DEBUG(7, FileSystem, "open passed bad filename, throwing exception.");
325        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::open] Invalid file name");
326    }
327
328
329    if (!exists(fileName)) {
330        DEBUG(6, FileSystem, "FileName does not exist in open, throwing exception.");
331        throw CF::FileException(CF::CFEEXIST, "[FileSystem::open] File does not exist.");
332    }
333
334//    fs::path filePath(root / fileName);
335
336    File_impl *file = new File_impl (fileName, root, read_Only, false);
337    CF::File_var fileServant = file->_this();
338
339    fileInfo newFile;
340    newFile.fileName = fileName;
341    newFile.servant = fileServant;
342    files.push_back(newFile);
343
344    return fileServant._retn();
345}
346
347
348void FileSystem_impl::mkdir (const char *directoryName) throw (CORBA::SystemException, CF::FileException, CF::InvalidFileName)
349{
350    DEBUG(6, FileSystem, "In mkdir with " << directoryName);
351
352    if (!ossieSupport::isValidFileName(directoryName)) {
353        DEBUG(7, FileSystem, "mkdir passed bad filename, throwing exception.");
354        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::mkdir] Invalid file name");
355    }
356
357    fs::path dirPath(root / directoryName);
358
359    if (fs::exists(dirPath))
360        throw CF::FileException (CF::CFEEXIST, "[FileSystem::mkdir] Directory exists.");
361
362    fs::path::iterator walkPath(dirPath.begin());
363    fs::path currentPath;
364    while (walkPath != dirPath.end()) {
365        DEBUG(9, FileSystem, "Walking path to create directories, current path " << currentPath.string());
366        currentPath /= *walkPath;
367        if (!fs::exists(currentPath)) {
368            DEBUG(9, FileSystem, "Creating directory " << currentPath.string());
369            try {
370                fs::create_directory(currentPath);
371            } catch (...) {
372                throw CF::FileException (CF::CFENFILE, "[FileSystem::mkdir] Failed to create directory");
373            }
374        }
375        ++walkPath;
376    }
377}
378
379void FileSystem_impl::removeDirectory(const fs::path &dirPath, bool doRemove)
380{
381
382    fs::directory_iterator end_itr; // past the end
383    for (fs::directory_iterator itr(dirPath); itr != end_itr; ++itr) {
384        if (fs::is_directory(*itr))
385            removeDirectory(*itr, doRemove);
386        else {
387            DEBUG(7, FileSystem, "Directory not empty in rmdir.");
388            throw CF::FileException();
389        }
390    }
391
392    if (doRemove)
393        fs::remove(dirPath);
394}
395
396void FileSystem_impl::rmdir (const char *directoryName) throw (CORBA::SystemException, CF::FileException, CF::InvalidFileName)
397{
398    DEBUG(6, FileSystem, "In rmdir with " << directoryName);
399
400    if (!ossieSupport::isValidFileName(directoryName)) {
401        DEBUG(7, FileSystem, "rmdir passed bad directory name, throwing exception.");
402        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::rmdir] Invalid directory name");
403    }
404
405    fs::path dirPath(root / directoryName);
406
407    if (!fs::exists(dirPath) || !fs::is_directory(dirPath)) {
408        DEBUG(7, FileSystem, "rmdir passed non_existant name or name is not a directory, throwing exception.");
409        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::rmdir] Invalid directory name");
410    }
411
412// See the JTAP test for rmdir to understand this
413    removeDirectory(dirPath, false); // Test for only empty directories
414    removeDirectory(dirPath, true);  // Only empty directories, remove them all
415}
416
417
418void FileSystem_impl::query (CF::Properties & fileSysProperties) throw (CORBA::SystemException, CF::FileSystem::UnknownFileSystemProperties)
419{
420    DEBUG(6, FileSystem, "In query");
421#if 0  ///\todo Implement query operations
422    bool check;
423
424    for (unsigned int i = 0; i < fileSysProperties.length (); i++) {
425        check = false;
426        if (strcmp (fileSysProperties[i].id, CF::FileSystem::SIZE) == 0) {
427            struct stat fileStat;
428            stat (root, &fileStat);
429//          fileSysProperties[i].value <<= fileStat.st_size;  /// \bug FIXME
430            check = true;
431        }
432        if (strcmp (fileSysProperties[i].id,
433                    CF::FileSystem::AVAILABLE_SIZE) == 0) {
434//to complete
435        }
436        if (!check)
437            throw CF::FileSystem::UnknownFileSystemProperties ();
438    }
439#endif
440}
441
442///\todo Implement File object reference clean up.
443#endif /* end of else of ifdef USE_OPENCPI_FS */
Note: See TracBrowser for help on using the browser.