00001 #include <time.h>
00002 #include <utime.h>
00003 #include <unistd.h>
00004 #include <fcntl.h>
00005
00006 #include <iostream>
00007 #include <fstream>
00008 #include <string>
00009
00010 #include "util.h"
00011 #include "NSError.h"
00012 #include "NVActiveDB.h"
00013 #include "readline.h"
00014
00015 using namespace std;
00016
00017
00018 unsigned long NVActiveDB::hash(const char *strg)
00019 {
00020 unsigned long h = 1;
00021 const char *p = strg;
00022 while (p[0]) {
00023 h = (h * (p[0]) + p[1]) % NVActiveDB_HASHSIZE;
00024 if (!p[1])
00025 break;
00026 p += 2;
00027 }
00028 return h;
00029 }
00030
00031 void NVActiveDB::sset(GroupInfo & gi, int flags)
00032 {
00033
00034 const char *gidata;
00035 unsigned int gisz;
00036 Record *head = o2r(hashtab[hash(gi.name())]);
00037 Record *r = head;
00038
00039 while (r) {
00040 r = o2r(r->next);
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 if (strcmp(((GroupInfo *) r->datap())->name(), gi.name())
00053 == 0) {
00054 gi.setctime(((GroupInfo *) r->datap())->ctime());
00055 gi.getraw(&gidata, &gisz);
00056 if (gisz != r->szdata) {
00057 VERB(slog.
00058 p(Logger::
00059 Error) <<
00060 "NVActiveDB::set: Size of new record not equal original record size. Should have been impossible.\n");
00061 } else {
00062 memcpy(r->datap(), gidata, gisz);
00063 }
00064 break;
00065 }
00066 if (r == head)
00067 r = NULL;
00068 }
00069
00070 if (!r) {
00071 if (flags & update_only) {
00072
00073 VERB(slog.
00074 p(Logger::
00075 Error) <<
00076 "NVActiveDB::set: Cannot find requested record\n");
00077 } else {
00078 const char *buf;
00079 unsigned int bufsz;
00080 nvtime_t now;
00081 nvtime(&now);
00082 gi.setctime(now);
00083 gi.getraw(&buf, &bufsz);
00084 NVHash::add(hash(gi.name()), buf, bufsz);
00085 }
00086 }
00087 }
00088
00089 void NVActiveDB::add(GroupInfo & gi)
00090 {
00091 VERB(slog.p(Logger::Debug) << "NVActiveDB::add(GroupInfo &gi)\n)");
00092 const char *buf;
00093 unsigned int bufsz;
00094 gi.getraw(&buf, &bufsz);
00095 NVHash::add(hash(gi.name()), buf, bufsz);
00096 }
00097
00098 int NVActiveDB::get(const char *group, GroupInfo * gi)
00099 {
00100 VERB(slog.
00101 p(Logger::Debug) << "NVActiveDB::get(" << group << ",&gi)\n");
00102 lock(ShrdLock);
00103 Record *head = o2r(hashtab[hash(group)]);
00104 Record *r = head;
00105
00106 while (r) {
00107 r = o2r(r->next);
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 if (strcmp(((GroupInfo *) r->datap())->name(), group) == 0) {
00120 gi->setraw(r->datap(), r->szdata);
00121 break;
00122 }
00123 if (r == head)
00124 r = NULL;
00125 }
00126 lock(UnLock);
00127
00128 if (!r)
00129 return -1;
00130 return 0;
00131 }
00132
00133 int NVActiveDB::hasgroup(const char *group)
00134 {
00135 VERB(slog.
00136 p(Logger::Info) << "NVActiveDB::hasgroup(" << group << ")\n");
00137 lock(ShrdLock);
00138 Record *head = o2r(hashtab[hash(group)]);
00139 Record *r = head;
00140
00141 while (r) {
00142 r = o2r(r->next);
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 if (strcmp(((GroupInfo *) r->datap())->name(), group) == 0) {
00155 break;
00156 }
00157 if (r == head)
00158 r = NULL;
00159 }
00160 lock(UnLock);
00161
00162 if (!r)
00163 return 0;
00164 return 1;
00165 }
00166
00167 void NVActiveDB::read(istream & is, const char *filter, int flags)
00168 {
00169 VERB(slog.
00170 p(Logger::Debug) << "NVActiveDB::read(&is,*filter,flags)\n");
00171
00172 GroupInfo gd;
00173 string line;
00174 time_t now;
00175
00176 lock(NVcontainer::ExclLock);
00177 if (flags & F_CLEAR)
00178 clear();
00179 while (!is.eof()) {
00180
00181
00182 nlreadline(is, line, 0);
00183 if (line == ".")
00184 break;
00185
00186 if (!filter || matchgroup(filter, line.c_str()) > 0) {
00187
00188 gd.set(line.c_str());
00189 if (flags & F_STORE_READONLY)
00190 gd.setflag('n');
00191 sset(gd);
00192 }
00193 }
00194 time(&now);
00195 setmtime(now);
00196 lock(NVcontainer::UnLock);
00197 }
00198
00199 void NVActiveDB::write(ostream & os,
00200 nvtime_t ctime, int mode, const char *filter)
00201 {
00202 VERB(slog.
00203 p(Logger::Debug) << "NVActiveDB::write(&os,ctime,...)\n");
00204
00205 NVHashIter nvhi(*this);
00206 GroupInfo gd;
00207 const char *buf;
00208 unsigned int bufsz;
00209
00210 for (nvhi.first(); nvhi.valid(); nvhi.next()) {
00211 nvhi.data(&buf, &bufsz);
00212 gd.setraw(buf, bufsz);
00213 if (((!filter) ||
00214 ((matchgroup(filter, gd.name()) > 0))) &&
00215 ctime < gd.ctime()) {
00216 if (mode == m_active)
00217 os << gd << "\r\n";
00218 else
00219 os << gd.name() << " " << gd.
00220 ctime() << " news\r\n";
00221 if (!os.good()) {
00222 throw SystemError("Cannot write GroupList",
00223 errno, ERROR_LOCATION);
00224 }
00225 }
00226 }
00227 }