00001
#include "wvfam.h"
00002
00003
#ifdef WITH_FAM
00004
00005
#include "wvistreamlist.h"
00006
#include <sys/stat.h>
00007
00008
void WvFamBase::close()
00009 {
00010
if (!s)
00011
return;
00012
00013
WvIStreamList::globallist.
unlink(s);
00014
delete s;
00015 s = 0;
00016
00017
if (FAMClose(&fc) == -1)
00018
log(WvLog::Error,
"%s\n", FamErrlist[FAMErrno]);
00019 }
00020
00021
bool WvFamBase::isok()
const
00022
{
00023
if (s && s->isok())
00024
return true;
00025
00026
return false;
00027 }
00028
00029
int WvFamBase::_monitordir(
WvString *dir)
00030 {
00031
if (
isok() && !FAMMonitorDirectory(&fc, *dir, &fr, dir))
00032
return fr.reqnum;
00033
00034
log(WvLog::Error,
"Could not monitor directory '%s'.\n", *dir);
00035
return -1;
00036 }
00037
00038
int WvFamBase::_monitorfile(
WvString *file)
00039 {
00040
if (
isok() && !FAMMonitorFile(&fc, *file, &fr, 0))
00041
return fr.reqnum;
00042
00043
log(WvLog::Error,
"Could not monitor file '%s'.\n", *file);
00044
return -1;
00045 }
00046
00047
void WvFamBase::_unmonitor(
int reqid)
00048 {
00049
if (!
isok())
00050
return;
00051
00052 fr.reqnum = reqid;
00053 FAMCancelMonitor(&fc, &fr);
00054 }
00055
00056
void WvFamBase::_callback()
00057 {
00058
int famstatus;
00059
00060
while((famstatus = FAMPending(&fc)) && famstatus != -1
00061 && FAMNextEvent(&fc, &fe) > 0)
00062 {
00063
if (fe.code == FAMChanged || fe.code == FAMDeleted
00064 || fe.code == FAMCreated)
00065 {
00066
if (!fe.userdata)
00067 cb(
WvString(fe.filename), WvFamEvent(fe.code),
false);
00068
00069
00070
00071
else
00072 cb(
WvString(
"%s/%s",
00073 *reinterpret_cast<WvString *>(fe.userdata),
00074 fe.filename), WvFamEvent(fe.code),
true);
00075 }
00076 }
00077
00078
if (famstatus == -1)
00079
log(WvLog::Error,
"%s\n", FamErrlist[FAMErrno]);
00080 }
00081
00082
bool WvFamBase::fam_ok()
00083 {
00084 FAMConnection fc;
00085
00086
if (FAMOpen(&fc) == -1)
00087 {
00088 fprintf(stderr,
"Error connecting to FAM: %s\n", FamErrlist[FAMErrno]);
00089
return false;
00090 }
00091
if (FAMClose(&fc) == -1)
00092 {
00093 fprintf(stderr,
"Error diconnecting from FAM: %s\n",
00094 FamErrlist[FAMErrno]);
00095
return false;
00096 }
00097
return true;
00098 }
00099
00100
void WvFamBase::setup()
00101 {
00102
if (FAMOpen(&fc) == -1)
00103 {
00104
log(WvLog::Error,
"Could not connect to FAM: %s\n",
00105 FamErrlist[FAMErrno]);
00106 }
00107
else
00108 {
00109 s =
new WvFDStream(fc.fd);
00110
00111 s->setcallback(
WvStreamCallback(
this, &WvFamBase::callback), 0);
00112
00113
WvIStreamList::globallist.append(s,
false);
00114 }
00115 }
00116
00117
void WvFam::monitordir(
WvStringParm dir)
00118 {
00119
if (reqs[dir])
00120
return;
00121
00122 WvFamReq *req =
new WvFamReq(dir, 0,
true);
00123 req->data = _monitordir(&req->key);
00124
00125
if (req->data <= 0)
00126 {
00127
delete req;
00128
return;
00129 }
00130
00131 reqs.add(req,
true);
00132 }
00133
00134
void WvFam::monitorfile(
WvStringParm file)
00135 {
00136
if (reqs[file])
00137
return;
00138
00139 WvFamReq *req =
new WvFamReq(file, 0,
true);
00140 req->data = _monitorfile(&req->key);
00141
00142
if (req->data <= 0)
00143 {
00144
delete req;
00145
return;
00146 }
00147
00148 reqs.add(req,
true);
00149 }
00150
00151
void WvFam::monitor(
WvStringParm path)
00152 {
00153
struct stat buf;
00154
if (stat(path, &buf))
00155
return;
00156
00157
if (S_ISDIR(buf.st_mode))
00158 monitordir(path);
00159
else
00160 monitorfile(path);
00161 }
00162
00163
void WvFam::unmonitor(
WvStringParm path)
00164 {
00165 WvFamReq *req = reqs[path];
00166
if (!req)
00167
return;
00168
00169 _unmonitor(req->data);
00170 reqs.remove(req);
00171 }
00172
00173
#endif