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