VFileBrowser.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:12k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. static const char* const VFileBrowser_cxx_Version =
  51.     "$Id: VFileBrowser.cxx,v 1.5 2001/06/29 05:36:28 bko Exp $";
  52. #include <errno.h>
  53. #include <stdio.h>
  54. #if !defined(__FreeBSD__) && !defined(WIN32)
  55. #include <ftw.h>
  56. #else
  57. #include "ftw.h"
  58. #endif
  59. #include <sys/stat.h>
  60. #include <unistd.h>
  61. #ifndef WIN32
  62. #include <strstream.h>
  63. #include <fstream.h>
  64. #else
  65. #include <strstream>
  66. #include <fstream>
  67. #endif
  68. #include "VFileBrowser.hxx"
  69. #include "VIoException.hxx"
  70. #include "cpLog.h"
  71. pthread_mutex_t VFileBrowser::_lock = PTHREAD_MUTEX_INITIALIZER;
  72. VFileBrowser::DirList VFileBrowser::_dirList;
  73. list < string > VFileBrowser::_toDel;
  74. VFileBrowser::VFileBrowser(const string& root)
  75.         : _root(root)
  76. {}
  77. void
  78. VFileBrowser::removeAll(const string& dirPath) throw (VIoException&)
  79. {
  80.     VFileBrowser::_toDel.clear();
  81.     string dPath(_root);
  82.     if (dirPath.size() && dirPath[0] != '/') dPath += "/";
  83.     // path should always be something like /usr/local/vocal or more
  84.     // to be safe, abort if too short
  85.     dPath += dirPath;
  86.     if (dPath.size() < 16)
  87.     {
  88.         cpLog(LOG_ERR, "Cowardly refusing to delete tree with path",
  89.               " name less than 16 characters : %s", dPath.c_str());
  90.         return ;
  91.     }
  92.     pthread_mutex_lock(&VFileBrowser::_lock);
  93.     VFileBrowser::_dirList.clear();
  94.     if (ftw(dPath.c_str(), VFileBrowser::addnode, 5) , 0)
  95.     {
  96.         char buf[256];
  97.         sprintf(buf, "Failed to get dir listing for %s, reason %s",
  98.                 dPath.c_str(), strerror(errno));
  99.         cpLog(LOG_ALERT, buf);
  100.         pthread_mutex_unlock(&_lock);
  101.         throw VIoException(buf, __FILE__, __LINE__, errno);
  102.     }
  103.     list < string > ::iterator itr;
  104.     for (itr = _toDel.begin(); itr != _toDel.end(); itr++)
  105.     {
  106.         if (::remove((*itr).c_str()) == -1)
  107.         {
  108.             char buf[256];
  109.             sprintf(buf, "Failed to remove file %s, reason %s",
  110.                     (*itr).c_str(),
  111.                     strerror(errno));
  112.             throw VIoException (buf, __FILE__, __LINE__, errno);
  113.         }
  114.     }
  115.     pthread_mutex_unlock(&VFileBrowser::_lock);
  116. }
  117. VFileBrowser::DirList
  118. VFileBrowser::directory(const string& dirPath) throw (VIoException&)
  119. {
  120.     string dPath(_root);
  121.     if (dirPath.size() && dirPath[0] != '/') dPath += "/";
  122.     dPath += dirPath;
  123.     pthread_mutex_lock(&VFileBrowser::_lock);
  124.     VFileBrowser::_dirList.clear();
  125.     if (ftw(dPath.c_str(), VFileBrowser::pftw, 5) , 0)
  126.     {
  127.         char buf[256];
  128.         sprintf(buf, "Failed to get dir listing for %s, reason %s",
  129.                 dPath.c_str(), strerror(errno));
  130.         cpLog(LOG_ALERT, buf);
  131.         pthread_mutex_unlock(&_lock);
  132.         throw VIoException(buf, __FILE__, __LINE__, errno);
  133.     }
  134.     DirList dirList = VFileBrowser::_dirList;
  135.     pthread_mutex_unlock(&VFileBrowser::_lock);
  136.     return (dirList);
  137. }
  138. int
  139. VFileBrowser::pftw(const char* fName, const struct stat* sb, int flag)
  140. {
  141.     if (flag == FTW_F)
  142.     {
  143.         VFile aFile(fName, flag, sb->st_mtime);
  144.         _dirList.push_back(aFile);
  145.     }
  146.     return 0;
  147. }
  148. int
  149. VFileBrowser::addnode(const char* fName, const struct stat* sb, int flag)
  150. {
  151.     _toDel.push_front(fName);
  152.     return 0;
  153. }
  154. void
  155. VFileBrowser::mkDir(const string& dirPath) throw (VIoException&)
  156. {
  157.     string reconPath(_root);
  158.     reconPath += dirPath;
  159.     cpLog(LOG_DEBUG, "Creating dir %s", reconPath.c_str());
  160.     if (!dirExists(dirPath))
  161.     {
  162.         if (dirPath.find("/") != string::npos)
  163.         {
  164.             //Directory has subdir in it
  165.             //use mkdir -p which would create all
  166.             //the directories in path
  167.             string cmdStr("mkdir -p ");
  168.             cmdStr += reconPath;
  169.             if (system(cmdStr.c_str()) < 0)
  170.             {
  171.                 char buf[256];
  172.                 ostrstream ostr(buf, 256);
  173.                 ostr << "Failed to create dir :"
  174.                 << reconPath
  175.                 << ", reason:"
  176.                 << strerror(errno)
  177.                 << ends;
  178.                 cpLog(LOG_ALERT, ostr.str());
  179.                 throw VIoException(ostr.str(), __FILE__, __LINE__, errno);
  180.             }
  181.         }
  182.     }
  183. }
  184. void
  185. VFileBrowser::writeFile(const string& filePath, const string& content) throw (VIoException)
  186. {
  187.     string path;
  188.     string::size_type pos = filePath.find_last_of("/");
  189.     if (pos != string::npos)
  190.         path = filePath.substr(0, filePath.find_last_of("/"));
  191.     mkDir(path);
  192.     string reconPath(_root);
  193.     reconPath += filePath;
  194.     ofstream fout(reconPath.c_str());
  195.     if (fout.bad())
  196.     {
  197.         char buf[256];
  198.         ostrstream ostr(buf, 256);
  199.         ostr << "Failed to open file :"
  200.         << reconPath
  201.         << ", reason:"
  202.         << strerror(errno)
  203.         << ends;
  204.         cpLog(LOG_DEBUG, ostr.str());
  205.         throw VIoException(ostr.str(), __FILE__, __LINE__, errno);
  206.     }
  207.     //Write data to file
  208.     fout << content.c_str();
  209.     fout.flush();
  210. }
  211. void
  212. VFileBrowser::writeFile(const string& filePath, const string& content,
  213.                         time_t timestamp)
  214. throw (VIoException)
  215. {
  216.     struct stat statBuf;
  217.     struct utimbuf timeBuf;
  218.     string path;
  219.     string::size_type pos = filePath.find_last_of("/");
  220.     if (pos != string::npos)
  221.         path = filePath.substr(0, filePath.find_last_of("/"));
  222.     mkDir(path);
  223.     string reconPath(_root);
  224.     reconPath += filePath;
  225.     ofstream fout(reconPath.c_str());
  226.     if (fout.bad())
  227.     {
  228.         char buf[256];
  229.         ostrstream ostr(buf, 256);
  230.         ostr << "Failed to open file :"
  231.         << reconPath
  232.         << ", reason:"
  233.         << strerror(errno)
  234.         << ends;
  235.         cpLog(LOG_DEBUG, ostr.str());
  236.         throw VIoException(ostr.str(), __FILE__, __LINE__, errno);
  237.         return ;
  238.     }
  239.     //Write data to file
  240.     fout << content.c_str();
  241.     fout.flush();
  242.     if (stat(reconPath.c_str(), &statBuf) < 0)
  243.     {
  244.         cpLog(LOG_ERR, "Failed to stat file that was just created!");
  245.         throw VIoException(
  246.             "Failed to stat file that was just created!",
  247.             __FILE__, __LINE__, errno);
  248.         return ;
  249.     }
  250.     timeBuf.actime = statBuf.st_atime;
  251.     timeBuf.modtime = timestamp;
  252.     if (utime(reconPath.c_str(), &timeBuf) < 0)
  253.     {
  254.         cpLog(LOG_ERR,
  255.               "Failed to set timestamp for file that was just created!");
  256.         throw VIoException(
  257.             "Failed to set timestamp for file that was just created!",
  258.             __FILE__, __LINE__, errno);
  259.         return ;
  260.     }
  261. }
  262. void
  263. VFileBrowser::writeFile(const string& filePath, const string& content,
  264.                         time_t *timestamp)
  265. throw (VIoException)
  266. {
  267.     struct stat statBuf;
  268.     string path;
  269.     string::size_type pos = filePath.find_last_of("/");
  270.     if (pos != string::npos)
  271.         path = filePath.substr(0, filePath.find_last_of("/"));
  272.     mkDir(path);
  273.     string reconPath(_root);
  274.     reconPath += filePath;
  275.     ofstream fout(reconPath.c_str());
  276.     if (fout.bad())
  277.     {
  278.         char buf[256];
  279.         ostrstream ostr(buf, 256);
  280.         ostr << "Failed to open file :"
  281.         << reconPath
  282.         << ", reason:"
  283.         << strerror(errno)
  284.         << ends;
  285.         cpLog(LOG_DEBUG, ostr.str());
  286.         throw VIoException(ostr.str(), __FILE__, __LINE__, errno);
  287.         return ;
  288.     }
  289.     //Write data to file
  290.     fout << content.c_str();
  291.     fout.flush();
  292.     if (stat(reconPath.c_str(), &statBuf) < 0)
  293.     {
  294.         cpLog(LOG_ERR, "Failed to stat file that was just created!");
  295.         throw VIoException(
  296.             "Failed to stat file that was just created!",
  297.             __FILE__, __LINE__, errno);
  298.         return ;
  299.     }
  300.     *timestamp = statBuf.st_mtime;
  301. }
  302. bool
  303. VFileBrowser::dirExists(const string& dirName)
  304. {
  305.     struct stat stBuf;
  306.     if (stat(dirName.c_str(), &stBuf) < 0)
  307.     {
  308.         return false;
  309.     }
  310.     return true;
  311. }
  312. void
  313. VFileBrowser::rename(const string& oldPath, const string& newPath)
  314. throw (VIoException&)
  315. {
  316.     string rOldPath(_root);
  317.     rOldPath += oldPath;
  318.     string rNewPath(_root);
  319.     rNewPath += newPath;
  320.     cpLog(LOG_DEBUG, "Renaming frm %s to %s", rOldPath.c_str(), rNewPath.c_str());
  321.     if (::rename(rOldPath.c_str(), rNewPath.c_str()) < 0)
  322.     {
  323.         char buf[256];
  324.         ostrstream ostr(buf, 256);
  325.         ostr << "Failed to rename file from :"
  326.         << oldPath
  327.         << " to "
  328.         << newPath
  329.         << ", reason:"
  330.         << strerror(errno)
  331.         << ends;
  332.         cpLog(LOG_DEBUG, ostr.str());
  333.         throw VIoException(ostr.str(), __FILE__, __LINE__, errno);
  334.     }
  335. }
  336. void
  337. VFileBrowser::atomicWrite(const string& fileName, const string& contents)
  338. {
  339.     //First write file to modify dir and then rename it to its
  340.     //original locaion
  341.     string modFileName;
  342.     string::size_type pos = fileName.find_last_of("/");
  343.     modFileName = fileName;
  344.     if (pos != string::npos)
  345.     {
  346.         modFileName.insert(pos, "/modify/");
  347.     }
  348.     else
  349.     {
  350.         modFileName = "/modify/";
  351.         modFileName += fileName;
  352.     }
  353.     writeFile(modFileName, contents);
  354.     //Now move the file to its original location
  355.     rename(modFileName, fileName);
  356. }
  357. ///Remove a file
  358. void
  359. VFileBrowser::remove(const string& filePath) throw (VIoException&)
  360. {
  361.     string reconPath(_root);
  362.     if (filePath.size() && filePath[0] != '/') reconPath += "/";
  363.     reconPath += filePath;
  364.     if (::remove(reconPath.c_str()) == -1)
  365.     {
  366.         char buf[256];
  367.         sprintf(buf, "Failed to remove file %s, reason %s", reconPath.c_str(),
  368.                 strerror(errno));
  369.         throw VIoException (buf, __FILE__, __LINE__, errno);
  370.     }
  371. }
  372. bool
  373. VFileBrowser::fileExists(const VFile& file)
  374. {
  375.     struct stat statBuf;
  376.     if (stat(file.getFullName().c_str(), &statBuf) < 0)
  377.     {
  378.         if (errno == ENOENT) return false;
  379.         cpLog(LOG_ALERT, "Failed to get stat for file %s", file.getFullName().c_str());
  380.         return false;
  381.     }
  382.     return true;
  383. }
  384. int
  385. VFileBrowser::fileSize(const VFile& file)
  386. {
  387.     struct stat statBuf;
  388.     if (stat(file.getFullName().c_str(), &statBuf) < 0)
  389.     {
  390.         cpLog(LOG_ALERT, "Failed to get stat for file %s", file.getFullName().c_str());
  391.         return 0;
  392.     }
  393.     return statBuf.st_size;
  394. }