aboutsummaryrefslogtreecommitdiffstats
path: root/doc/api-documentation/html/filemgr_8cpp-source.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/api-documentation/html/filemgr_8cpp-source.html')
-rw-r--r--doc/api-documentation/html/filemgr_8cpp-source.html278
1 files changed, 278 insertions, 0 deletions
diff --git a/doc/api-documentation/html/filemgr_8cpp-source.html b/doc/api-documentation/html/filemgr_8cpp-source.html
new file mode 100644
index 0000000..b807e94
--- /dev/null
+++ b/doc/api-documentation/html/filemgr_8cpp-source.html
@@ -0,0 +1,278 @@
+<!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>