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

Telnet服务器

开发平台:

Unix_Linux

  1. /*
  2.     Pirate Bulletin Board System
  3.     Copyright (C) 1990, Edward Luke, lush@Athena.EE.MsState.EDU
  4.     Eagles Bulletin Board System
  5.     Copyright (C) 1992, Raymond Rocker, rocker@rock.b11.ingr.com
  6.                         Guy Vega, gtvega@seabass.st.usm.edu
  7.                         Dominic Tynes, dbtynes@seabass.st.usm.edu
  8.     Firebird Bulletin Board System
  9.     Copyright (C) 1996, Hsien-Tsung Chang, Smallpig.bbs@bbs.cs.ccu.edu.tw
  10.                         Peng Piaw Foong, ppfoong@csie.ncu.edu.tw
  11.     This program is free software; you can redistribute it and/or modify
  12.     it under the terms of the GNU General Public License as published by
  13.     the Free Software Foundation; either version 1, or (at your option)
  14.     any later version.
  15.     This program is distributed in the hope that it will be useful,
  16.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.     GNU General Public License for more details.
  19. */
  20. /*
  21. $Id: record.c,v 1.2 2000/01/24 12:10:27 edwardc Exp $
  22. */
  23. #include "bbs.h"
  24. #define BUFSIZE (8192)
  25. int
  26. safewrite(fd, buf, size)
  27. int     fd;
  28. char   *buf;
  29. int     size;
  30. {
  31. int     cc, sz = size, origsz = size;
  32. char   *bp = buf;
  33. #ifdef POSTBUG
  34. if (size == sizeof(struct fileheader)) {
  35. char    tmp[80];
  36. struct stat stbuf;
  37. struct fileheader *fbuf = (struct fileheader *) buf;
  38. setbpath(tmp, fbuf->filename);
  39. if (!isalpha(fbuf->filename[0]) || stat(tmp, &stbuf) == -1)
  40. if (fbuf->filename[0] != 'M' || fbuf->filename[1] != '.') {
  41. report("safewrite: foiled attempt to write bugged recordn");
  42. return origsz;
  43. }
  44. }
  45. #endif
  46. do {
  47. cc = write(fd, bp, sz);
  48. if ((cc < 0) && (errno != EINTR)) {
  49. report("safewrite err!");
  50. return -1;
  51. }
  52. if (cc > 0) {
  53. bp += cc;
  54. sz -= cc;
  55. }
  56. } while (sz > 0);
  57. return origsz;
  58. }
  59. #ifdef POSTBUG
  60. char    bigbuf[10240];
  61. int     numtowrite;
  62. int     bug_possible = 0;
  63. int
  64. saverecords(filename, size, pos)
  65. char   *filename;
  66. int     size, pos;
  67. {
  68. int     fd;
  69. if (!bug_possible)
  70. return 0;
  71. if ((fd = open(filename, O_RDONLY)) == -1)
  72. return -1;
  73. if (pos > 5)
  74. numtowrite = 5;
  75. else
  76. numtowrite = 4;
  77. lseek(fd, (off_t) ((pos - numtowrite - 1) * size), SEEK_SET);
  78. read(fd, bigbuf, numtowrite * size);
  79. }
  80. int
  81. restorerecords(filename, size, pos)
  82. char   *filename;
  83. int     size, pos;
  84. {
  85. int     fd;
  86. if (!bug_possible)
  87. return 0;
  88. if ((fd = open(filename, O_WRONLY)) == -1)
  89. return -1;
  90. flock(fd, LOCK_EX);
  91. lseek(fd, (off_t) ((pos - numtowrite - 1) * size), SEEK_SET);
  92. safewrite(fd, bigbuf, numtowrite * size);
  93. report("post bug poison set out!");
  94. flock(fd, LOCK_UN);
  95. bigbuf[0] = '';
  96. close(fd);
  97. }
  98. #endif
  99. long
  100. get_num_records(filename, size)
  101. char   *filename;
  102. int     size;
  103. {
  104. struct stat st;
  105. if (stat(filename, &st) == -1)
  106. return 0;
  107. return (st.st_size / size);
  108. }
  109. int
  110. append_record(filename, record, size)
  111. char   *filename;
  112. char   *record;
  113. int     size;
  114. {
  115. int     fd;
  116. #ifdef POSTBUG
  117. int     numrecs = (int) get_num_records(filename, size);
  118. bug_possible = 1;
  119. if (size == sizeof(struct fileheader) && numrecs && (numrecs % 4 == 0))
  120. saverecords(filename, size, numrecs + 1);
  121. #endif
  122. if ((fd = open(filename, O_WRONLY | O_CREAT, 0644)) == -1) {
  123. perror("open");
  124. return -1;
  125. }
  126. flock(fd, LOCK_EX);
  127. lseek(fd, 0, SEEK_END);
  128. if (safewrite(fd, record, size) == -1)
  129. report("apprec write err!");
  130. flock(fd, LOCK_UN);
  131. close(fd);
  132. #ifdef POSTBUG
  133. if (size == sizeof(struct fileheader) && numrecs && (numrecs % 4 == 0))
  134. restorerecords(filename, size, numrecs + 1);
  135. bug_possible = 0;
  136. #endif
  137. return 0;
  138. }
  139. void
  140. toobigmesg()
  141. {
  142. fprintf(stderr, "record size too big!!n");
  143. }
  144. int
  145. apply_record(filename, fptr, size)
  146. char   *filename;
  147. int     (*fptr) ();
  148. int     size;
  149. {
  150. char    abuf[BUFSIZE];
  151. int     fd;
  152. if (size > BUFSIZE) {
  153. toobigmesg();
  154. return -1;
  155. }
  156. if ((fd = open(filename, O_RDONLY, 0)) == -1)
  157. return -1;
  158. while (read(fd, abuf, size) == size)
  159. if ((*fptr) (abuf) == QUIT) {
  160. close(fd);
  161. return QUIT;
  162. }
  163. close(fd);
  164. return 0;
  165. }
  166. int
  167. search_record(filename, rptr, size, fptr, farg)
  168. char   *filename;
  169. char   *rptr;
  170. int     size;
  171. int     (*fptr) ();
  172. char   *farg;
  173. {
  174. int     fd;
  175. int     id = 1;
  176. if ((fd = open(filename, O_RDONLY, 0)) == -1)
  177. return 0;
  178. while (read(fd, rptr, size) == size) {
  179. if ((*fptr) (farg, rptr)) {
  180. close(fd);
  181. return id;
  182. }
  183. id++;
  184. }
  185. close(fd);
  186. return 0;
  187. }
  188. int
  189. get_record(filename, rptr, size, id)
  190. char   *filename;
  191. char   *rptr;
  192. int     size, id;
  193. {
  194. int     fd;
  195. if ((fd = open(filename, O_RDONLY, 0)) == -1)
  196. return -1;
  197. if (lseek(fd, (off_t) (size * (id - 1)), SEEK_SET) == -1) {
  198. close(fd);
  199. return -1;
  200. }
  201. if (read(fd, rptr, size) != size) {
  202. close(fd);
  203. return -1;
  204. }
  205. close(fd);
  206. return 0;
  207. }
  208. int
  209. get_records(filename, rptr, size, id, number)
  210. char   *filename;
  211. char   *rptr;
  212. int     size, id, number;
  213. {
  214. int     fd;
  215. int     n;
  216. if ((fd = open(filename, O_RDONLY, 0)) == -1)
  217. return -1;
  218. if (lseek(fd, (off_t) (size * (id - 1)), SEEK_SET) == -1) {
  219. close(fd);
  220. return 0;
  221. }
  222. if ((n = read(fd, rptr, size * number)) == -1) {
  223. close(fd);
  224. return -1;
  225. }
  226. close(fd);
  227. return (n / size);
  228. }
  229. int
  230. substitute_record(filename, rptr, size, id)
  231. char   *filename;
  232. char   *rptr;
  233. int     size, id;
  234. {
  235. int     fd;
  236. #ifdef POSTBUG
  237. if (size == sizeof(struct fileheader) && (id > 1) && ((id - 1) % 4 == 0))
  238. saverecords(filename, size, id);
  239. #endif
  240. if ((fd = open(filename, O_WRONLY | O_CREAT, 0644)) == -1)
  241. return -1;
  242. flock(fd, LOCK_EX);
  243. if (lseek(fd, (off_t) (size * (id - 1)), SEEK_SET) == -1)
  244. report("subrec seek err");
  245. if (safewrite(fd, rptr, size) != size)
  246. report("subrec write err");
  247. flock(fd, LOCK_UN);
  248. close(fd);
  249. #ifdef POSTBUG
  250. if (size == sizeof(struct fileheader) && (id > 1) && ((id - 1) % 4 == 0))
  251. restorerecords(filename, size, id);
  252. #endif
  253. return 0;
  254. }
  255. void
  256. tmpfilename(filename, tmpfile, deleted)
  257. char   *filename, *tmpfile, *deleted;
  258. {
  259. char   *ptr, *delfname, *tmpfname;
  260. strcpy(tmpfile, filename);
  261. delfname = ".deleted";
  262. tmpfname = ".tmpfile";
  263. if ((ptr = strrchr(tmpfile, '/')) != NULL) {
  264. strcpy(ptr + 1, delfname);
  265. strcpy(deleted, tmpfile);
  266. strcpy(ptr + 1, tmpfname);
  267. } else {
  268. strcpy(deleted, delfname);
  269. strcpy(tmpfile, tmpfname);
  270. }
  271. }
  272. int
  273. delete_record(filename, size, id)
  274. char   *filename;
  275. int     size, id;
  276. {
  277. char    tmpfile[STRLEN], deleted[STRLEN];
  278. char    abuf[BUFSIZE];
  279. int     fdr, fdw, fd;
  280. int     count;
  281. if (size > BUFSIZE) {
  282. toobigmesg();
  283. return -1;
  284. }
  285. tmpfilename(filename, tmpfile, deleted);
  286. if ((fd = open(".dellock", O_RDWR | O_CREAT | O_APPEND, 0644)) == -1)
  287. return -1;
  288. flock(fd, LOCK_EX);
  289. if ((fdr = open(filename, O_RDONLY, 0)) == -1) {
  290. report("delrec open err");
  291. flock(fd, LOCK_UN);
  292. close(fd);
  293. return -1;
  294. }
  295. if ((fdw = open(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0644)) == -1) {
  296. flock(fd, LOCK_UN);
  297. report("delrec tmp err");
  298. close(fd);
  299. close(fdr);
  300. return -1;
  301. }
  302. count = 1;
  303. while (read(fdr, abuf, size) == size)
  304. if (id != count++ && (safewrite(fdw, abuf, size) == -1)) {
  305. unlink(tmpfile);
  306. close(fdr);
  307. close(fdw);
  308. report("delrec write err");
  309. flock(fd, LOCK_UN);
  310. close(fd);
  311. return -1;
  312. }
  313. close(fdr);
  314. close(fdw);
  315. if (rename(filename, deleted) == -1 ||
  316. rename(tmpfile, filename) == -1) {
  317. flock(fd, LOCK_UN);
  318. report("delrec rename err");
  319. close(fd);
  320. return -1;
  321. }
  322. flock(fd, LOCK_UN);
  323. close(fd);
  324. return 0;
  325. }
  326. int
  327. delete_range(filename, id1, id2)
  328. char   *filename;
  329. int     id1, id2;
  330. {
  331. struct fileheader fhdr;
  332. char    tmpfile[STRLEN], deleted[STRLEN];
  333. int     fdr, fdw, fd;
  334. int     count;
  335. tmpfilename(filename, tmpfile, deleted);
  336. if ((fd = open(".dellock", O_RDWR | O_CREAT | O_APPEND, 0644)) == -1)
  337. return -1;
  338. flock(fd, LOCK_EX);
  339. if ((fdr = open(filename, O_RDONLY, 0)) == -1) {
  340. flock(fd, LOCK_UN);
  341. close(fd);
  342. return -1;
  343. }
  344. if ((fdw = open(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0644)) == -1) {
  345. close(fdr);
  346. flock(fd, LOCK_UN);
  347. close(fd);
  348. return -1;
  349. }
  350. count = 1;
  351. while (read(fdr, &fhdr, sizeof(fhdr)) == sizeof(fhdr)) {
  352. if (count < id1 || count > id2 || fhdr.accessed[0] & FILE_MARKED) {
  353. if ((safewrite(fdw, &fhdr, sizeof(fhdr)) == -1)) {
  354. unlink(tmpfile);
  355. close(fdw);
  356. close(fdr);
  357. flock(fd, LOCK_UN);
  358. close(fd);
  359. return -1;
  360. }
  361. } else {
  362. char   *t;
  363. char    buf[STRLEN], fullpath[STRLEN];
  364. strcpy(buf, filename);
  365. if ((t = strrchr(buf, '/')) != NULL)
  366. *t = '';
  367. sprintf(fullpath, "%s/%s", buf, fhdr.filename);
  368. unlink(fullpath);
  369. }
  370. count++;
  371. }
  372. close(fdw);
  373. close(fdr);
  374. if (rename(filename, deleted) == -1) {
  375. flock(fd, LOCK_UN);
  376. close(fd);
  377. return -1;
  378. }
  379. if (rename(tmpfile, filename) == -1) {
  380. flock(fd, LOCK_UN);
  381. close(fd);
  382. return -1;
  383. }
  384. flock(fd, LOCK_UN);
  385. close(fd);
  386. return 0;
  387. }
  388. int
  389. update_file(dirname, size, ent, filecheck, fileupdate)
  390. char   *dirname;
  391. int     size, ent;
  392. int     (*filecheck) ();
  393. void    (*fileupdate) ();
  394. {
  395. char    abuf[BUFSIZE];
  396. int     fd;
  397. if (size > BUFSIZE) {
  398. toobigmesg();
  399. return -1;
  400. }
  401. if ((fd = open(dirname, O_RDWR)) == -1)
  402. return -1;
  403. flock(fd, LOCK_EX);
  404. if (lseek(fd, (off_t) (size * (ent - 1)), SEEK_SET) != -1) {
  405. if (read(fd, abuf, size) == size)
  406. if ((*filecheck) (abuf)) {
  407. lseek(fd, (off_t) (-size), SEEK_CUR);
  408. (*fileupdate) (abuf);
  409. if (safewrite(fd, abuf, size) != size) {
  410. report("update err");
  411. flock(fd, LOCK_UN);
  412. close(fd);
  413. return -1;
  414. }
  415. flock(fd, LOCK_UN);
  416. close(fd);
  417. return 0;
  418. }
  419. }
  420. lseek(fd, 0, SEEK_SET);
  421. while (read(fd, abuf, size) == size) {
  422. if ((*filecheck) (abuf)) {
  423. lseek(fd, (off_t) (-size), SEEK_CUR);
  424. (*fileupdate) (abuf);
  425. if (safewrite(fd, abuf, size) != size) {
  426. report("update err");
  427. flock(fd, LOCK_UN);
  428. close(fd);
  429. return -1;
  430. }
  431. flock(fd, LOCK_UN);
  432. close(fd);
  433. return 0;
  434. }
  435. }
  436. flock(fd, LOCK_UN);
  437. close(fd);
  438. return -1;
  439. }
  440. int
  441. delete_file(dirname, size, ent, filecheck)
  442. char   *dirname;
  443. int     size, ent;
  444. int     (*filecheck) ();
  445. {
  446. char    abuf[BUFSIZE];
  447. int     fd;
  448. struct stat st;
  449. long    numents;
  450. if (size > BUFSIZE) {
  451. toobigmesg();
  452. return -1;
  453. }
  454. if ((fd = open(dirname, O_RDWR)) == -1)
  455. return -1;
  456. flock(fd, LOCK_EX);
  457. fstat(fd, &st);
  458. numents = ((long) st.st_size) / size;
  459. if (((long) st.st_size) % size != 0)
  460. fprintf(stderr, "align errn");
  461. if (lseek(fd, (off_t) (size * (ent - 1)), SEEK_SET) != -1) {
  462. if (read(fd, abuf, size) == size)
  463. if ((*filecheck) (abuf)) {
  464. int     i;
  465. for (i = ent; i < numents; i++) {
  466. if (lseek(fd, (off_t) (i * size), SEEK_SET) == -1)
  467. break;
  468. if (read(fd, abuf, size) != size)
  469. break;
  470. if (lseek(fd, (off_t) ((i - 1) * size), SEEK_SET) == -1)
  471. break;
  472. if (safewrite(fd, abuf, size) != size)
  473. break;
  474. }
  475. ftruncate(fd, (off_t) size * (numents - 1));
  476. flock(fd, LOCK_UN);
  477. close(fd);
  478. return 0;
  479. }
  480. }
  481. lseek(fd, 0, SEEK_SET);
  482. ent = 1;
  483. while (read(fd, abuf, size) == size) {
  484. if ((*filecheck) (abuf)) {
  485. int     i;
  486. for (i = ent; i < numents; i++) {
  487. if (lseek(fd, (off_t) ((i + 1) * size), SEEK_SET) == -1)
  488. break;
  489. if (read(fd, abuf, size) != size)
  490. break;
  491. if (lseek(fd, (off_t) (i * size), SEEK_SET) == -1)
  492. break;
  493. if (safewrite(fd, abuf, size) != size)
  494. break;
  495. }
  496. ftruncate(fd, (off_t) size * (numents - 1));
  497. flock(fd, LOCK_UN);
  498. close(fd);
  499. return 0;
  500. }
  501. ent++;
  502. }
  503. flock(fd, LOCK_UN);
  504. close(fd);
  505. return -1;
  506. }