root/ossiedev/trunk/system/ossie/framework/FileSystem_impl.cpp @ 9924

Revision 9924, 13.4 KB (checked in by jgaeddert, 3 years ago)

filesystem: handling pre-processor conditions for when boost filesystem version is out of range

  • 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/* SCA */
24
25#include <iostream>
26#include <string>
27
28#include <fnmatch.h>
29
30#include <boost/filesystem/operations.hpp>
31#include <boost/filesystem/path.hpp>
32#include <boost/filesystem/exception.hpp>
33#ifndef BOOST_VERSION
34#include <boost/version.hpp>
35#endif
36
37#if BOOST_VERSION < 103499
38#  include <boost/filesystem/cerrno.hpp>
39#elif BOOST_VERSION < 103799
40#  include <boost/cerrno.hpp>
41#else
42#  warning "unknown boost version"
43#  include <boost/cerrno.hpp>
44#endif
45
46namespace fs = boost::filesystem;
47
48#include "ossie/FileSystem_impl.h"
49#include "ossie/debug.h"
50
51FileSystem_impl::FileSystem_impl ()
52{
53    DEBUG(6, FileSystem, "In constructor.");
54
55    if (fs::path::default_name_check_writable())
56        fs::path::default_name_check(fs::portable_posix_name);
57
58    root = fs::initial_path();
59
60    init ();
61}
62
63
64FileSystem_impl::FileSystem_impl (const char *_root)
65{
66    DEBUG(6, FileSystem, "In constructor with " << _root);
67
68    root = _root;
69
70    init ();
71}
72
73
74void
75FileSystem_impl::init ()
76{
77    DEBUG(6, FileSystem, "In init()");
78}
79
80FileSystem_impl::~FileSystem_impl ()
81{
82    DEBUG(6, FileSystem, "In destructor.");
83}
84
85void FileSystem_impl::remove (const char *fileName) throw (CORBA::SystemException, CF::FileException, CF::InvalidFileName)
86{
87    DEBUG(6, FileSystem, "In remove with " << fileName);
88
89    if (!ossieSupport::isValidFileName(fileName)) {
90        DEBUG(7, FileSystem, "remove passed bad filename, throwing exception.");
91        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::remove] Invalid file name");
92    }
93
94    fs::path fname(root / fileName);
95
96    DEBUG(6, FileSystem, "About to remove file " << fname.string());
97    bool exists = fs::remove(fname);
98
99    if (!exists) {
100        DEBUG(6, FileSystem, "Attempt to remove non-existant file.");
101        throw (CF::FileException (CF::CFEEXIST, "[FileSystem_impl::remove] Error removing file from file system"));
102    }
103}
104
105void FileSystem_impl::copy (const char *sourceFileName, const char *destinationFileName) throw (CORBA::SystemException, CF::InvalidFileName, CF::FileException)
106{
107    DEBUG(6, FileSystem, "In copy from " << sourceFileName << " to " << destinationFileName);
108
109    if (sourceFileName[0] != '/' || destinationFileName[0] != '/' || !ossieSupport::isValidFileName(sourceFileName) || !ossieSupport::isValidFileName(destinationFileName)) {
110        DEBUG(7, FileSystem, "copy passed bad filename, throwing exception.");
111        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::copy] Invalid file name");
112    }
113
114    try {
115        fs::path sFile(root / sourceFileName);
116        fs::path dFile(root / destinationFileName);
117
118        if (fs::is_directory(sFile))
119            return;
120
121        fs::copy_file(sFile, dFile);
122#if BOOST_VERSION < 103499
123    } catch (const fs::filesystem_error &ex) {
124        if (ex.system_error() == ENOENT)
125            throw CF::FileException(CF::CFENOENT, ex.what());
126#elif BOOST_VERSION < 103799
127    } catch (const boost::system::system_error &ex ) {
128        if (ex.code().value() == ENOENT)
129            throw CF::FileException(CF::CFENOENT, ex.what());
130#else
131    } catch (const boost::system::system_error &ex ) {
132        throw CF::FileException(CF::CFENOENT, ex.what());
133#endif
134    }
135}
136
137CORBA::Boolean FileSystem_impl::exists (const char *fileName)
138throw (CORBA::SystemException, CF::InvalidFileName)
139{
140    DEBUG(6, FileSystem, "In exists with " << fileName);
141
142    if (fileName[0] != '/' || !ossieSupport::isValidFileName(fileName)) {
143        DEBUG(7, FileSystem, "exists passed bad filename, throwing exception.");
144        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::exists] Invalid file name");
145    }
146
147    fs::path fname(root / fileName);
148
149    DEBUG(9, FileSystem, "Check for file " << fname.string());
150
151    return(fs::exists(fname));
152}
153
154void FileSystem_impl::recursiveList(const fs::path& dirPath, const char* pattern, CF::FileSystem::FileInformationSequence_var& fis)
155{
156    DEBUG(4, FileSystem, "Entering recursiveList")
157
158    try {
159        fs::path filePath(pattern, fs::no_check);
160        std::string searchPattern(filePath.leaf());
161        unsigned int idx = fis->length();
162        DEBUG(4, FileSystem, "In list with path " << dirPath.string() << ", and pattern " << searchPattern);
163        fs::directory_iterator end_itr; // past the end
164        for (fs::directory_iterator itr(dirPath); itr != end_itr; ++itr) {
165            if (fs::is_directory(*itr)) recursiveList(*itr, pattern, fis);
166            DEBUG(9, FileSystem, "In list checking file " << itr->leaf());
167            if (fnmatch(searchPattern.c_str(), itr->leaf().c_str(), 0) == 0) {
168                DEBUG(9, FileSystem, "Match in list with " << itr->leaf());
169                fis->length(idx + 1);
170
171                if (fs::is_directory(*itr)) {
172                    std::string tmp(itr->leaf());
173                    tmp += "/";
174                    fis[idx].name = CORBA::string_dup(tmp.c_str());
175                    fis[idx].kind = CF::FileSystem::DIRECTORY;
176                    fis[idx].size = 0;
177                } else {
178                    std::string full_path = dirPath.string();
179                    full_path += "/";
180                    full_path += itr->leaf();
181                    fis[idx].name = CORBA::string_dup(full_path.c_str());
182                    fis[idx].kind = CF::FileSystem::PLAIN;
183                    fis[idx].size = fs::file_size(*itr);
184                }
185                /// \todo fix file creation time and last access time
186                CF::Properties prop;
187                prop.length(3);
188                prop[0].id = CORBA::string_dup(CF::FileSystem::CREATED_TIME_ID);
189                prop[0].value <<= fs::last_write_time(*itr);
190                prop[1].id = CORBA::string_dup(CF::FileSystem::MODIFIED_TIME_ID);
191                prop[1].value <<= fs::last_write_time(*itr);
192                prop[2].id = CORBA::string_dup(CF::FileSystem::LAST_ACCESS_TIME_ID);
193                prop[2].value <<= fs::last_write_time(*itr);
194                fis[idx].fileProperties = prop;
195                ++idx;
196            }
197        }
198        DEBUG(4, FileSystem, "About to return from list.");
199#if BOOST_VERSION < 103499
200    } catch (const fs::filesystem_error &ex) {
201        DEBUG(9, FileSystem, "Caught exception in list, error_code " << ex.system_error());
202
203        if (ex.system_error() == EINVAL)
204            throw CF::InvalidFileName(CF::CFEINVAL, ex.what());
205#elif BOOST_VERSION < 103799
206    } catch (const boost::system::system_error &ex) {
207        DEBUG(9, FileSystem, "Caught exception in list, error_code " << ex.code().value());
208        if (ex.code().value() == EINVAL)
209            throw CF::InvalidFileName(CF::CFEINVAL, ex.what());
210#else
211    } catch (const boost::system::system_error &ex) {
212        throw CF::FileException(CF::CFNOTSET, ex.what());
213#endif
214    }
215    DEBUG(4, FileSystem, "Leaving recursiveList")
216}
217
218/// \todo: modify to search the pattern as a regular expression
219CF::FileSystem::FileInformationSequence* FileSystem_impl::list (const char *pattern) throw (CORBA::SystemException, CF::FileException, CF::InvalidFileName)
220{
221    DEBUG(6, FileSystem, "In list with " << pattern);
222
223    const fs::path rootDirPath(root);
224    CF::FileSystem::FileInformationSequence_var result = new CF::FileSystem::FileInformationSequence;
225    result->length(0);
226
227    recursiveList(rootDirPath, pattern, result);
228
229    return result._retn();
230}
231
232
233CF::File_ptr FileSystem_impl::create (const char *fileName) throw (CORBA::SystemException, CF::InvalidFileName, CF::FileException)
234{
235    DEBUG(6, FileSystem, "In create with " << fileName);
236
237    if (!ossieSupport::isValidFileName(fileName)) {
238        DEBUG(7, FileSystem, "create passed bad filename, throwing exception.");
239        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::create] Invalid file name");
240    }
241
242    if (exists(fileName)) {
243        DEBUG(6, FileSystem, "FileName exists in create, throwing exception.");
244        throw CF::FileException(CF::CFEEXIST, "File exists.");
245    }
246
247    File_impl *file = new File_impl (fileName, root, false, true);
248    CF::File_var fileServant = file->_this();
249
250    fileInfo newFile;
251    newFile.fileName = fileName;
252    newFile.servant = fileServant;
253    files.push_back(newFile);
254
255    return fileServant._retn();
256}
257
258CF::File_ptr FileSystem_impl::open (const char *fileName, CORBA::Boolean read_Only) throw (CORBA::SystemException, CF::InvalidFileName, CF::FileException)
259{
260    DEBUG(6, FileSystem, "In open with " << fileName);
261
262    if (!ossieSupport::isValidFileName(fileName)) {
263        DEBUG(7, FileSystem, "open passed bad filename, throwing exception.");
264        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::open] Invalid file name");
265    }
266
267
268    if (!exists(fileName)) {
269        DEBUG(6, FileSystem, "FileName does not exist in open, throwing exception.");
270        throw CF::FileException(CF::CFEEXIST, "[FileSystem::open] File does not exist.");
271    }
272
273//    fs::path filePath(root / fileName);
274
275    File_impl *file = new File_impl (fileName, root, read_Only, false);
276    CF::File_var fileServant = file->_this();
277
278    fileInfo newFile;
279    newFile.fileName = fileName;
280    newFile.servant = fileServant;
281    files.push_back(newFile);
282
283    return fileServant._retn();
284}
285
286
287void FileSystem_impl::mkdir (const char *directoryName) throw (CORBA::SystemException, CF::FileException, CF::InvalidFileName)
288{
289    DEBUG(6, FileSystem, "In mkdir with " << directoryName);
290
291    if (!ossieSupport::isValidFileName(directoryName)) {
292        DEBUG(7, FileSystem, "mkdir passed bad filename, throwing exception.");
293        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::mkdir] Invalid file name");
294    }
295
296    fs::path dirPath(root / directoryName);
297
298    if (fs::exists(dirPath))
299        throw CF::FileException (CF::CFEEXIST, "[FileSystem::mkdir] Directory exists.");
300
301    fs::path::iterator walkPath(dirPath.begin());
302    fs::path currentPath;
303    while (walkPath != dirPath.end()) {
304        DEBUG(9, FileSystem, "Walking path to create directories, current path " << currentPath.string());
305        currentPath /= *walkPath;
306        if (!fs::exists(currentPath)) {
307            DEBUG(9, FileSystem, "Creating directory " << currentPath.string());
308            try {
309                fs::create_directory(currentPath);
310            } catch (...) {
311                throw CF::FileException (CF::CFENFILE, "[FileSystem::mkdir] Failed to create directory");
312            }
313        }
314        ++walkPath;
315    }
316}
317
318void FileSystem_impl::removeDirectory(const fs::path &dirPath, bool doRemove)
319{
320
321    fs::directory_iterator end_itr; // past the end
322    for (fs::directory_iterator itr(dirPath); itr != end_itr; ++itr) {
323        if (fs::is_directory(*itr))
324            removeDirectory(*itr, doRemove);
325        else {
326            DEBUG(7, FileSystem, "Directory not empty in rmdir.");
327            throw CF::FileException();
328        }
329    }
330
331    if (doRemove)
332        fs::remove(dirPath);
333}
334
335void FileSystem_impl::rmdir (const char *directoryName) throw (CORBA::SystemException, CF::FileException, CF::InvalidFileName)
336{
337    DEBUG(6, FileSystem, "In rmdir with " << directoryName);
338
339    if (!ossieSupport::isValidFileName(directoryName)) {
340        DEBUG(7, FileSystem, "rmdir passed bad directory name, throwing exception.");
341        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::rmdir] Invalid directory name");
342    }
343
344    fs::path dirPath(root / directoryName);
345
346    if (!fs::exists(dirPath) || !fs::is_directory(dirPath)) {
347        DEBUG(7, FileSystem, "rmdir passed non_existant name or name is not a directory, throwing exception.");
348        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::rmdir] Invalid directory name");
349    }
350
351// See the JTAP test for rmdir to understand this
352    removeDirectory(dirPath, false); // Test for only empty directories
353    removeDirectory(dirPath, true);  // Only empty directories, remove them all
354}
355
356
357void FileSystem_impl::query (CF::Properties & fileSysProperties) throw (CORBA::SystemException, CF::FileSystem::UnknownFileSystemProperties)
358{
359    DEBUG(6, FileSystem, "In query");
360#if 0  ///\todo Implement query operations
361    bool check;
362
363    for (unsigned int i = 0; i < fileSysProperties.length (); i++) {
364        check = false;
365        if (strcmp (fileSysProperties[i].id, CF::FileSystem::SIZE) == 0) {
366            struct stat fileStat;
367            stat (root, &fileStat);
368//          fileSysProperties[i].value <<= fileStat.st_size;  /// \bug FIXME
369            check = true;
370        }
371        if (strcmp (fileSysProperties[i].id,
372                    CF::FileSystem::AVAILABLE_SIZE) == 0) {
373//to complete
374        }
375        if (!check)
376            throw CF::FileSystem::UnknownFileSystemProperties ();
377    }
378#endif
379}
380
381///\todo Implement File object reference clean up.
Note: See TracBrowser for help on using the browser.