his.c
上传用户:minyiyu
上传日期:2018-12-24
资源大小:864k
文件大小:10k
源码类别:

Telnet服务器

开发平台:

Unix_Linux

  1. /*  $Revision: 1.1 $
  2. **
  3. **  History file routines.
  4. */
  5. #include "innbbsconf.h"
  6. #include "bbslib.h"
  7. #include "his.h"
  8. #define STATIC static
  9. /*STATIC char HIShistpath[] = _PATH_HISTORY;*/
  10. STATIC FILE *HISwritefp;
  11. STATIC int HISreadfd;
  12. STATIC int HISdirty;
  13. STATIC int HISincore = XINDEX_DBZINCORE;
  14. STATIC char *LogName = "xindexchan";
  15. #ifndef EXPIREDAYS
  16. #define EXPIREDAYS 4
  17. #endif
  18. #ifndef DEFAULT_HIST_SIZE
  19. #define DEFAULT_HIST_SIZE 100000
  20. #endif
  21. hisincore(flag)
  22. int     flag;
  23. {
  24. HISincore = flag;
  25. }
  26. makedbz(histpath, entry)
  27. char   *histpath;
  28. long    entry;
  29. {
  30. long    size;
  31. size = dbzsize(entry);
  32. dbzfresh(histpath, size, 't', 0, 1);
  33. dbmclose();
  34. }
  35. void    HISsetup();
  36. void    HISclose();
  37. void
  38. mkhistory(srchist)
  39. char   *srchist;
  40. {
  41. FILE   *hismaint;
  42. time_t  lasthist, now;
  43. char    maintbuff[256];
  44. char   *ptr;
  45. hismaint = fopen(srchist, "r");
  46. if (hismaint == NULL) {
  47. return;
  48. } {
  49. char    newhistpath[1024];
  50. char    newhistdirpath[1024];
  51. char    newhistpagpath[1024];
  52. sprintf(newhistpath, "%s.n", srchist);
  53. sprintf(newhistdirpath, "%s.n.dir", srchist);
  54. sprintf(newhistpagpath, "%s.n.pag", srchist);
  55. if (!isfile(newhistdirpath) || !isfile(newhistpagpath)) {
  56. makedbz(newhistpath, DEFAULT_HIST_SIZE);
  57. }
  58. myHISsetup(newhistpath);
  59. while (fgets(maintbuff, sizeof(maintbuff), hismaint) != NULL) {
  60. datum   key;
  61. ptr = (char *) strchr(maintbuff, 't');
  62. if (ptr != NULL) {
  63. *ptr = '';
  64. ptr++;
  65. }
  66. key.dptr = maintbuff;
  67. key.dsize = strlen(maintbuff);
  68. myHISwrite(&key, ptr);
  69. }
  70. (void) HISclose();
  71. /*
  72.  * rename(newhistpath, srchist);
  73.  * rename(newhistdirpath, fileglue("%s.dir", srchist));
  74.  * rename(newhistpagpath, fileglue("%s.pag", srchist));
  75.  */
  76. }
  77. fclose(hismaint);
  78. }
  79. time_t
  80. gethisinfo()
  81. {
  82. FILE   *hismaint;
  83. time_t  lasthist, now;
  84. char    maintbuff[4096];
  85. char   *ptr;
  86. hismaint = fopen(HISTORY, "r");
  87. if (hismaint == NULL) {
  88. return 0;
  89. }
  90. fgets(maintbuff, sizeof(maintbuff), hismaint);
  91. fclose(hismaint);
  92. ptr = (char *) strchr(maintbuff, 't');
  93. if (ptr != NULL) {
  94. ptr++;
  95. lasthist = atol(ptr);
  96. return lasthist;
  97. }
  98. return 0;
  99. }
  100. void
  101. HISmaint()
  102. {
  103. FILE   *hismaint;
  104. time_t  lasthist, now;
  105. char    maintbuff[4096];
  106. char   *ptr;
  107. if (!isfile(HISTORY)) {
  108. makedbz(HISTORY, DEFAULT_HIST_SIZE);
  109. }
  110. hismaint = fopen(HISTORY, "r");
  111. if (hismaint == NULL) {
  112. return;
  113. }
  114. fgets(maintbuff, sizeof(maintbuff), hismaint);
  115. ptr = (char *) strchr(maintbuff, 't');
  116. if (ptr != NULL) {
  117. ptr++;
  118. lasthist = atol(ptr);
  119. time(&now);
  120. if (lasthist + 86400 * Expiredays * 2 < now) {
  121. char    newhistpath[1024];
  122. char    newhistdirpath[1024];
  123. char    newhistpagpath[1024];
  124. (void) HISclose();
  125. sprintf(newhistpath, "%s.n", HISTORY);
  126. sprintf(newhistdirpath, "%s.n.dir", HISTORY);
  127. sprintf(newhistpagpath, "%s.n.pag", HISTORY);
  128. if (!isfile(newhistdirpath)) {
  129. makedbz(newhistpath, DEFAULT_HIST_SIZE);
  130. }
  131. myHISsetup(newhistpath);
  132. while (fgets(maintbuff, sizeof(maintbuff), hismaint) != NULL) {
  133. datum   key;
  134. ptr = (char *) strchr(maintbuff, 't');
  135. if (ptr != NULL) {
  136. *ptr = '';
  137. ptr++;
  138. lasthist = atol(ptr);
  139. } else {
  140. continue;
  141. }
  142. if (lasthist + 99600 * Expiredays < now)
  143. continue;
  144. key.dptr = maintbuff;
  145. key.dsize = strlen(maintbuff);
  146. myHISwrite(&key, ptr);
  147. }
  148. (void) HISclose();
  149. rename(HISTORY, (char *) fileglue("%s.o", HISTORY));
  150. rename(newhistpath, HISTORY);
  151. rename(newhistdirpath, (char *) fileglue("%s.dir", HISTORY));
  152. rename(newhistpagpath, (char *) fileglue("%s.pag", HISTORY));
  153. (void) HISsetup();
  154. }
  155. }
  156. fclose(hismaint);
  157. }
  158. /*
  159. **  Set up the history files.
  160. */
  161. void
  162. HISsetup()
  163. {
  164. myHISsetup(HISTORY);
  165. }
  166. int
  167. myHISsetup(histpath)
  168. char   *histpath;
  169. {
  170. if (HISwritefp == NULL) {
  171. /* Open the history file for appending formatted I/O. */
  172. if ((HISwritefp = fopen(histpath, "a")) == NULL) {
  173. syslog(LOG_CRIT, "%s cant fopen %s %m", LogName, histpath);
  174. exit(1);
  175. }
  176. CloseOnExec((int) fileno(HISwritefp), TRUE);
  177. /* Open the history file for reading. */
  178. if ((HISreadfd = open(histpath, O_RDONLY)) < 0) {
  179. syslog(LOG_CRIT, "%s cant open %s %m", LogName, histpath);
  180. exit(1);
  181. }
  182. CloseOnExec(HISreadfd, TRUE);
  183. /* Open the DBZ file. */
  184. /* (void)dbzincore(HISincore); */
  185. (void) dbzincore(HISincore);
  186. (void) dbzwritethrough(1);
  187. if (dbminit(histpath) < 0) {
  188. syslog(LOG_CRIT, "%s cant dbminit %s %m", histpath, LogName);
  189. exit(1);
  190. }
  191. }
  192. }
  193. /*
  194. **  Synchronize the in-core history file (flush it).
  195. */
  196. void
  197. HISsync()
  198. {
  199. if (HISdirty) {
  200. if (dbzsync()) {
  201. syslog(LOG_CRIT, "%s cant dbzsync %m", LogName);
  202. exit(1);
  203. }
  204. HISdirty = 0;
  205. }
  206. }
  207. /*
  208. **  Close the history files.
  209. */
  210. void
  211. HISclose()
  212. {
  213. if (HISwritefp != NULL) {
  214. /*
  215.  * Since dbmclose calls dbzsync we could replace this line
  216.  * with "HISdirty = 0;".  Oh well, it keeps the abstraction
  217.  * clean.
  218.  */
  219. HISsync();
  220. if (dbmclose() < 0)
  221. syslog(LOG_ERR, "%s cant dbmclose %m", LogName);
  222. if (fclose(HISwritefp) == EOF)
  223. syslog(LOG_ERR, "%s cant fclose history %m", LogName);
  224. HISwritefp = NULL;
  225. if (close(HISreadfd) < 0)
  226. syslog(LOG_ERR, "%s cant close history %m", LogName);
  227. HISreadfd = -1;
  228. }
  229. }
  230. #ifdef HISset
  231. /*
  232. **  File in the DBZ datum for a Message-ID, making sure not to copy any
  233. **  illegal characters.
  234. */
  235. STATIC void
  236. HISsetkey(p, keyp)
  237. register char *p;
  238. datum  *keyp;
  239. {
  240. static BUFFER MessageID;
  241. register char *dest;
  242. register int i;
  243. /* Get space to hold the ID. */
  244. i = strlen(p);
  245. if (MessageID.Data == NULL) {
  246. MessageID.Data = NEW(char, i + 1);
  247. MessageID.Size = i;
  248. } else if (MessageID.Size < i) {
  249. RENEW(MessageID.Data, char, i + 1);
  250. MessageID.Size = i;
  251. }
  252. for (keyp->dptr = dest = MessageID.Data; *p; p++)
  253. if (*p == HIS_FIELDSEP || *p == 'n')
  254. *dest++ = HIS_BADCHAR;
  255. else
  256. *dest++ = *p;
  257. *dest = '';
  258. keyp->dsize = dest - MessageID.Data + 1;
  259. }
  260. #endif
  261. /*
  262. **  Get the list of files under which a Message-ID is stored.
  263. */
  264. char   *
  265. HISfilesfor(key, output)
  266. datum  *key;
  267. datum  *output;
  268. {
  269. char   *dest;
  270. datum   val;
  271. off_t   offset;
  272. register char *p;
  273. register int i;
  274. int     Used;
  275. /* Get the seek value into the history file. */
  276. val = dbzfetch(*key);
  277. if (val.dptr == NULL || val.dsize != sizeof offset) {
  278. /* printf("fail here val.dptr %dn",val.dptr); */
  279. return NULL;
  280. }
  281. /* Get space. */
  282. if (output->dptr == NULL) {
  283. printf("fail here output->dptr nulln");
  284. return NULL;
  285. }
  286. /* Copy the value to an aligned spot. */
  287. for (p = val.dptr, dest = (char *) &offset, i = sizeof offset; --i >= 0;)
  288. *dest++ = *p++;
  289. if (lseek(HISreadfd, offset, SEEK_SET) == -1) {
  290. printf("fail here lseek %dn", offset);
  291. return NULL;
  292. }
  293. /* Read the text until n or EOF. */
  294. for (output->dsize = 0, Used = 0;;) {
  295. i = read(HISreadfd,
  296. &output->dptr[output->dsize], LEN - 1);
  297. if (i <= 0) {
  298. printf("fail here i %dn", i);
  299. return NULL;
  300. }
  301. Used += i;
  302. output->dptr[Used] = '';
  303. if ((p = (char *) strchr(output->dptr, 'n')) != NULL) {
  304. *p = '';
  305. break;
  306. }
  307. }
  308. /* Move past the first two fields -- Message-ID and date info. */
  309. if ((p = (char *) strchr(output->dptr, HIS_FIELDSEP)) == NULL) {
  310. printf("fail here no HIS_FILEn");
  311. return NULL;
  312. }
  313. return p + 1;
  314. /*
  315.  * if ((p = (char*)strchr(p + 1, HIS_FIELDSEP)) == NULL) return NULL;
  316.  */
  317. /* Translate newsgroup separators to slashes, return the fieldstart. */
  318. }
  319. /*
  320. **  Have we already seen an article?
  321. */
  322. #ifdef HISh
  323. BOOL
  324. HIShavearticle(MessageID)
  325. char   *MessageID;
  326. {
  327. datum   key;
  328. datum   val;
  329. HISsetkey(MessageID, &key);
  330. val = dbzfetch(key);
  331. return val.dptr != NULL;
  332. }
  333. #endif
  334. /*
  335. **  Turn a history filename entry from slashes to dots.  It's a pity
  336. **  we have to do this.
  337. */
  338. STATIC void
  339. HISslashify(p)
  340. register char *p;
  341. {
  342. register char *last;
  343. for (last = NULL; *p; p++) {
  344. if (*p == '/') {
  345. *p = '.';
  346. last = p;
  347. } else if (*p == ' ' && last != NULL)
  348. *last = '/';
  349. }
  350. if (last)
  351. *last = '/';
  352. }
  353. IOError(error)
  354. char   *error;
  355. {
  356. fprintf(stderr, "%sn", error);
  357. }
  358. /*BOOL*/
  359. myHISwrite(key, remain)
  360. datum  *key;
  361. char   *remain;
  362. {
  363. static char NOPATHS[] = "";
  364. long    offset;
  365. datum   val;
  366. int     i;
  367. val = dbzfetch(*key);
  368. if (val.dptr != NULL) {
  369. return FALSE;
  370. }
  371. flock(fileno(HISwritefp), LOCK_EX);
  372. offset = ftell(HISwritefp);
  373. i = fprintf(HISwritefp, "%s%c%s",
  374. key->dptr, HIS_FIELDSEP, remain);
  375. if (i == EOF || fflush(HISwritefp) == EOF) {
  376. /* The history line is now an orphan... */
  377. IOError("history");
  378. syslog(LOG_ERR, "%s cant write history %m", LogName);
  379. flock(fileno(HISwritefp), LOCK_UN);
  380. return FALSE;
  381. }
  382. /* Set up the database values and write them. */
  383. val.dptr = (char *) &offset;
  384. val.dsize = sizeof offset;
  385. if (dbzstore(*key, val) < 0) {
  386. IOError("my history database");
  387. syslog(LOG_ERR, "%s cant dbzstore %m", LogName);
  388. flock(fileno(HISwritefp), LOCK_UN);
  389. return FALSE;
  390. }
  391. if (++HISdirty >= ICD_SYNC_COUNT)
  392. HISsync();
  393. flock(fileno(HISwritefp), LOCK_UN);
  394. return TRUE;
  395. }
  396. /*
  397. **  Write a history entry.
  398. */
  399. BOOL
  400. HISwrite(key, date, paths)
  401. datum  *key;
  402. char   *paths;
  403. long    date;
  404. {
  405. static char NOPATHS[] = "";
  406. long    offset;
  407. datum   val;
  408. int     i;
  409. flock(fileno(HISwritefp), LOCK_EX);
  410. offset = ftell(HISwritefp);
  411. i = fprintf(HISwritefp, "%s%c%ld%c%sn",
  412. key->dptr, HIS_FIELDSEP, (long) date, HIS_FIELDSEP,
  413. paths);
  414. if (i == EOF || fflush(HISwritefp) == EOF) {
  415. /* The history line is now an orphan... */
  416. IOError("history");
  417. syslog(LOG_ERR, "%s cant write history %m", LogName);
  418. flock(fileno(HISwritefp), LOCK_UN);
  419. return FALSE;
  420. }
  421. /* Set up the database values and write them. */
  422. val.dptr = (char *) &offset;
  423. val.dsize = sizeof offset;
  424. if (dbzstore(*key, val) < 0) {
  425. IOError("history database");
  426. syslog(LOG_ERR, "%s cant dbzstore %m", LogName);
  427. flock(fileno(HISwritefp), LOCK_UN);
  428. return FALSE;
  429. }
  430. if (++HISdirty >= ICD_SYNC_COUNT)
  431. HISsync();
  432. flock(fileno(HISwritefp), LOCK_UN);
  433. return TRUE;
  434. }