Sophie

Sophie

distrib > Mandriva > 9.1 > ppc > by-pkgid > a74ec78bdb789d910d054e3918f3f007 > files > 315

libsword1-devel-1.5.5-2mdk.ppc.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>filemgr.cpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.2.15 -->
<center>
<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="namespaces.html">Namespace List</a> &nbsp; <a class="qindex" href="hierarchy.html">Class Hierarchy</a> &nbsp; <a class="qindex" href="classes.html">Alphabetical List</a> &nbsp; <a class="qindex" href="annotated.html">Compound List</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Compound Members</a> &nbsp; </center>
<hr><h1>filemgr.cpp</h1><div class="fragment"><pre>00001 <font class="comment">/******************************************************************************</font>
00002 <font class="comment"> *  filemgr.cpp - implementation of class FileMgr used for pooling file</font>
00003 <font class="comment"> *                                      handles</font>
00004 <font class="comment"> *</font>
00005 <font class="comment"> * $Id: filemgr_8cpp-source.html,v 1.3 2002/06/20 20:23:08 mgruner Exp $</font>
00006 <font class="comment"> *</font>
00007 <font class="comment"> * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)</font>
00008 <font class="comment"> *      CrossWire Bible Society</font>
00009 <font class="comment"> *      P. O. Box 2528</font>
00010 <font class="comment"> *      Tempe, AZ  85280-2528</font>
00011 <font class="comment"> *</font>
00012 <font class="comment"> * This program is free software; you can redistribute it and/or modify it</font>
00013 <font class="comment"> * under the terms of the GNU General Public License as published by the</font>
00014 <font class="comment"> * Free Software Foundation version 2.</font>
00015 <font class="comment"> *</font>
00016 <font class="comment"> * This program is distributed in the hope that it will be useful, but</font>
00017 <font class="comment"> * WITHOUT ANY WARRANTY; without even the implied warranty of</font>
00018 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU</font>
00019 <font class="comment"> * General Public License for more details.</font>
00020 <font class="comment"> *</font>
00021 <font class="comment"> */</font>
00022 
00023 <font class="preprocessor">#include &lt;filemgr.h&gt;</font>
00024 <font class="preprocessor">#include &lt;utilstr.h&gt;</font>
00025 
00026 <font class="preprocessor">#include &lt;dirent.h&gt;</font>
00027 <font class="preprocessor">#include &lt;fcntl.h&gt;</font>
00028 <font class="preprocessor">#include &lt;sys/stat.h&gt;</font>
00029 <font class="preprocessor">#include &lt;sys/types.h&gt;</font>
00030 <font class="preprocessor">#include &lt;stdio.h&gt;</font>
00031 <font class="preprocessor">#include &lt;string.h&gt;</font>
00032 <font class="preprocessor">#ifndef __GNUC__</font>
00033 <font class="preprocessor"></font><font class="preprocessor">#include &lt;io.h&gt;</font>
00034 <font class="preprocessor">#else</font>
00035 <font class="preprocessor"></font><font class="preprocessor">#include &lt;unistd.h&gt;</font>
00036 <font class="preprocessor">#endif</font>
00037 <font class="preprocessor"></font>
00038 <font class="comment">// ---------------- statics -----------------</font>
00039 FileMgr FileMgr::systemFileMgr;
00040 
00041 <font class="comment">// --------------- end statics --------------</font>
00042 
00043 
00044 FileDesc::FileDesc(FileMgr *parent, <font class="keywordtype">char</font> *path, <font class="keywordtype">int</font> mode, <font class="keywordtype">int</font> perms, <font class="keywordtype">bool</font> tryDowngrade) {
00045         this-&gt;parent = parent;
00046         this-&gt;path = 0;
00047         stdstr(&amp;this-&gt;path, path);
00048         this-&gt;mode = mode;
00049         this-&gt;perms = perms;
00050         this-&gt;tryDowngrade = tryDowngrade;
00051         offset = 0;
00052         fd = -77;
00053 }
00054 
00055 
00056 FileDesc::~FileDesc() {
00057         <font class="keywordflow">if</font> (fd &gt; 0)
00058                 close(fd);
00059                 
00060         <font class="keywordflow">if</font> (path)
00061                 <font class="keyword">delete</font> [] path;
00062 }
00063 
00064 
00065 <font class="keywordtype">int</font> FileDesc::getFd() {
00066         <font class="keywordflow">if</font> (fd == -77)
00067                 fd = parent-&gt;sysOpen(<font class="keyword">this</font>);
00068         <font class="keywordflow">return</font> fd;
00069 }
00070 
00071 
00072 FileMgr::FileMgr(<font class="keywordtype">int</font> maxFiles) {
00073         this-&gt;maxFiles = maxFiles;              <font class="comment">// must be at least 2</font>
00074         files = 0;
00075 }
00076 
00077 
00078 FileMgr::~FileMgr() {
00079         FileDesc *tmp;
00080         
00081         <font class="keywordflow">while</font>(files) {
00082                 tmp = files-&gt;next;
00083                 <font class="keyword">delete</font> files;
00084                 files = tmp;
00085         }
00086 }
00087 
00088 
00089 FileDesc *FileMgr::open(<font class="keywordtype">char</font> *path, <font class="keywordtype">int</font> mode, <font class="keywordtype">bool</font> tryDowngrade) {
00090         <font class="keywordflow">return</font> open(path, mode, S_IREAD | S_IWRITE, tryDowngrade);
00091 }
00092 
00093 FileDesc *FileMgr::open(<font class="keywordtype">char</font> *path, <font class="keywordtype">int</font> mode, <font class="keywordtype">int</font> perms, <font class="keywordtype">bool</font> tryDowngrade) {
00094         FileDesc **tmp, *tmp2;
00095         
00096         <font class="keywordflow">for</font> (tmp = &amp;files; *tmp; tmp = &amp;((*tmp)-&gt;next)) {
00097                 <font class="keywordflow">if</font> ((*tmp)-&gt;fd &lt; 0)             <font class="comment">// insert as first non-system_open file</font>
00098                         <font class="keywordflow">break</font>;
00099         }
00100 
00101         tmp2 = <font class="keyword">new</font> FileDesc(<font class="keyword">this</font>, path, mode, perms, tryDowngrade);
00102         tmp2-&gt;next = *tmp;
00103         *tmp = tmp2;
00104         
00105         <font class="keywordflow">return</font> tmp2;
00106 }
00107 
00108 
00109 <font class="keywordtype">void</font> FileMgr::close(FileDesc *file) {
00110         FileDesc **loop;
00111         
00112         <font class="keywordflow">for</font> (loop = &amp;files; *loop; loop = &amp;((*loop)-&gt;next)) {
00113                 <font class="keywordflow">if</font> (*loop == file) {
00114                         *loop = (*loop)-&gt;next;
00115                         <font class="keyword">delete</font> file;
00116                         <font class="keywordflow">break</font>;
00117                 }
00118         }
00119 }
00120 
00121 
00122 <font class="comment">// to truncate a file at its current position</font>
00123 <font class="comment">// leaving byte at current possition intact</font>
00124 <font class="comment">// deleting everything afterward.</font>
00125 <font class="keywordtype">signed</font> <font class="keywordtype">char</font> FileMgr::trunc(FileDesc *file) {
00126 
00127         <font class="keyword">static</font> <font class="keyword">const</font> <font class="keywordtype">char</font> *writeTest = <font class="stringliteral">"x"</font>;
00128         <font class="keywordtype">long</font> size = lseek(file-&gt;getFd(), 1, SEEK_CUR);
00129         <font class="keywordtype">char</font> nibble [ 32767 ];
00130         <font class="keywordtype">bool</font> writable = write(file-&gt;getFd(), writeTest, 1);
00131         <font class="keywordtype">int</font> bytes = 0;
00132 
00133         <font class="keywordflow">if</font> (writable) {
00134                 <font class="comment">// get tmpfilename</font>
00135                 <font class="keywordtype">char</font> *buf = <font class="keyword">new</font> <font class="keywordtype">char</font> [ strlen(file-&gt;path) + 10 ];
00136                 <font class="keywordtype">int</font> i;
00137                 <font class="keywordflow">for</font> (i = 0; i &lt; 9999; i++) {
00138                         sprintf(buf, <font class="stringliteral">"%stmp%.4d"</font>, file-&gt;path, i);
00139                         <font class="keywordflow">if</font> (!existsFile(buf))
00140                                 <font class="keywordflow">break</font>;
00141                 }
00142                 <font class="keywordflow">if</font> (i == 9999)
00143                         <font class="keywordflow">return</font> -2;
00144 
00145                 <font class="keywordtype">int</font> fd = ::open(buf, O_CREAT|O_RDWR, S_IREAD|S_IWRITE);
00146                 <font class="keywordflow">if</font> (fd &lt; 0)
00147                         <font class="keywordflow">return</font> -3;
00148         
00149                 lseek(file-&gt;getFd(), 0, SEEK_SET);
00150                 <font class="keywordflow">while</font> (size &gt; 0) {
00151                         bytes = read(file-&gt;getFd(), nibble, 32767);
00152                         write(fd, nibble, (bytes &lt; size)?bytes:size);
00153                         size -= bytes;
00154                 }
00155                 <font class="comment">// zero out the file</font>
00156                 ::close(file-&gt;fd);
00157                 file-&gt;fd = ::open(file-&gt;path, O_TRUNC, S_IREAD|S_IWRITE);
00158                 ::close(file-&gt;fd);
00159                 file-&gt;fd = -77; <font class="comment">// force file open by filemgr</font>
00160                 <font class="comment">// copy tmp file back (dumb, but must preserve file permissions)</font>
00161                 lseek(fd, 0, SEEK_SET);
00162                 <font class="keywordflow">do</font> {
00163                         bytes = read(fd, nibble, 32767);
00164                         write(file-&gt;getFd(), nibble, bytes);
00165                 } <font class="keywordflow">while</font> (bytes == 32767);
00166                 
00167                 ::close(fd);
00168                 ::close(file-&gt;fd);
00169                 unlink(buf);            <font class="comment">// remove our tmp file</font>
00170                 file-&gt;fd = -77; <font class="comment">// causes file to be swapped out forcing open on next call to getFd()</font>
00171         }
00172         <font class="keywordflow">else</font> { <font class="comment">// put offset back and return failure</font>
00173                 lseek(file-&gt;getFd(), -1, SEEK_CUR);
00174                 <font class="keywordflow">return</font> -1;
00175         }
00176         <font class="keywordflow">return</font> 0;
00177 }
00178 
00179 
00180 <font class="keywordtype">int</font> FileMgr::sysOpen(FileDesc *file) {
00181         FileDesc **loop;
00182         <font class="keywordtype">int</font> openCount = 1;              <font class="comment">// because we are presently opening 1 file, and we need to be sure to close files to accomodate, if necessary</font>
00183         
00184         <font class="keywordflow">for</font> (loop = &amp;files; *loop; loop = &amp;((*loop)-&gt;next)) {
00185 
00186                 <font class="keywordflow">if</font> ((*loop)-&gt;fd &gt; 0) {
00187                         <font class="keywordflow">if</font> (++openCount &gt; maxFiles) {
00188                                 (*loop)-&gt;offset = lseek((*loop)-&gt;fd, 0, SEEK_CUR);
00189                                 ::close((*loop)-&gt;fd);
00190                                 (*loop)-&gt;fd = -77;
00191                         }
00192                 }
00193 
00194                 <font class="keywordflow">if</font> (*loop == file) {
00195                         <font class="keywordflow">if</font> (*loop != files) {
00196                                 *loop = (*loop)-&gt;next;
00197                                 file-&gt;next = files;
00198                                 files = file;
00199                         }
00200                         <font class="keywordflow">if</font> ((!access(file-&gt;path, 04)) || ((file-&gt;mode &amp; O_CREAT) == O_CREAT)) { <font class="comment">// check for at least file exists / read access before we try to open</font>
00201                                 <font class="keywordtype">char</font> tries = (((file-&gt;mode &amp; O_RDWR) == O_RDWR) &amp;&amp; (file-&gt;tryDowngrade)) ? 2 : 1;  <font class="comment">// try read/write if possible</font>
00202                                 <font class="keywordflow">for</font> (<font class="keywordtype">int</font> i = 0; i &lt; tries; i++) {
00203                                         <font class="keywordflow">if</font> (i &gt; 0) {
00204                                                 file-&gt;mode = (file-&gt;mode &amp; ~O_RDWR);    <font class="comment">// remove write access</font>
00205                                                 file-&gt;mode = (file-&gt;mode | O_RDONLY);<font class="comment">// add read access</font>
00206                                         }
00207                                         file-&gt;fd = ::open(file-&gt;path, file-&gt;mode, file-&gt;perms);
00208 
00209                                         <font class="keywordflow">if</font> (file-&gt;fd &gt;= 0)
00210                                                 <font class="keywordflow">break</font>;
00211                                 }
00212 
00213                                 <font class="keywordflow">if</font> (file-&gt;fd &gt;= 0)
00214                                         lseek(file-&gt;fd, file-&gt;offset, SEEK_SET);
00215                         }
00216                         <font class="keywordflow">else</font> file-&gt;fd = -1;
00217                         <font class="keywordflow">if</font> (!*loop)
00218                                 <font class="keywordflow">break</font>;
00219                 }
00220         }
00221         <font class="keywordflow">return</font> file-&gt;fd;
00222 }
00223 
00224 
00225 <font class="keywordtype">signed</font> <font class="keywordtype">char</font> FileMgr::existsFile(<font class="keyword">const</font> <font class="keywordtype">char</font> *ipath, <font class="keyword">const</font> <font class="keywordtype">char</font> *ifileName)
00226 {
00227         <font class="keywordtype">int</font> len = strlen(ipath) + ((ifileName)?strlen(ifileName):0) + 3;
00228         <font class="keywordtype">char</font> *ch;
00229         <font class="keywordtype">char</font> *path = <font class="keyword">new</font> <font class="keywordtype">char</font> [ len ];
00230         strcpy(path, ipath);
00231         
00232         <font class="keywordflow">if</font> ((path[strlen(path)-1] == <font class="charliteral">'\\'</font>) || (path[strlen(path)-1] == <font class="charliteral">'/'</font>))
00233                 path[strlen(path)-1] = 0;
00234         
00235         <font class="keywordflow">if</font> (ifileName) {
00236                 ch = path + strlen(path);
00237                 sprintf(ch, <font class="stringliteral">"/%s"</font>, ifileName);
00238         }
00239         <font class="keywordtype">signed</font> <font class="keywordtype">char</font> retVal = !access(path, 04);
00240         <font class="keyword">delete</font> [] path;
00241         <font class="keywordflow">return</font> retVal;
00242 }
00243 
00244 
00245 <font class="keywordtype">signed</font> <font class="keywordtype">char</font> FileMgr::existsDir(<font class="keyword">const</font> <font class="keywordtype">char</font> *ipath, <font class="keyword">const</font> <font class="keywordtype">char</font> *idirName)
00246 {
00247         <font class="keywordtype">char</font> *ch;
00248         <font class="keywordtype">int</font> len = strlen(ipath) + ((idirName)?strlen(idirName):0) + 1;
00249         <font class="keywordflow">if</font> (idirName)
00250                 len +=  strlen(idirName);
00251         <font class="keywordtype">char</font> *path = <font class="keyword">new</font> <font class="keywordtype">char</font> [ len ];
00252         strcpy(path, ipath);
00253         
00254         <font class="keywordflow">if</font> ((path[strlen(path)-1] == <font class="charliteral">'\\'</font>) || (path[strlen(path)-1] == <font class="charliteral">'/'</font>))
00255                 path[strlen(path)-1] = 0;
00256         
00257         <font class="keywordflow">if</font> (idirName) {
00258                 ch = path + strlen(path);
00259                 sprintf(ch, <font class="stringliteral">"/%s"</font>, idirName);
00260         }
00261         <font class="keywordtype">signed</font> <font class="keywordtype">char</font> retVal = !access(path, 04);
00262      <font class="keyword">delete</font> [] path;
00263      <font class="keywordflow">return</font> retVal;
00264 }
</pre></div><hr><address align="right"><small>Generated on Thu Jun 20 22:12:59 2002 for The Sword Project by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 
width=110 height=53></a>1.2.15 </small></address>
</body>
</html>