isfcb.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
  24. /*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
  25. /*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
  26. /*%% (c) Copyright 1993, 1994 Novell, Inc. */
  27. /*%% $XConsortium: isfcb.c /main/3 1995/10/23 11:38:34 rswiston $ */
  28. /*
  29. * Copyright (c) 1988 by Sun Microsystems, Inc.
  30. */
  31. /*
  32. * isfcb.c
  33. *
  34. * Description: _ambuild()
  35. * File Control Block functions
  36. *
  37. *
  38. */
  39. #include <unistd.h>
  40. #include <stdlib.h>
  41. #include "isam_impl.h"
  42. #include <sys/stat.h>
  43. static int _create_datfile(), _create_indfile(), _create_varfile();
  44. static void _remove_datfile(), _remove_indfile(), _remove_varfile();
  45. Static int _open_datfile(), _open_indfile(), _open_varfile();
  46. /*
  47. * _isfcb_create(isfname, crdat, crind, crvar, owner, group, u_mask, errcode)
  48. *
  49. * Create ISAM file: create UNIX files (dat/ind/var),
  50. * and initialize File Control Block.
  51. *
  52. * Return 0 if create is successful, or -1 if any error. In the case of
  53. *an error, the errcode block is set.
  54. *
  55. * crdat, 0/1 flag
  56. * crind, 0/1 flag
  57. * crvar, 0/1 flag
  58. */
  59. Fcb *
  60. _isfcb_create(char *isfname, int crdat, int crind, int crvar,
  61. int owner, int group, int u_mask, struct errcode *errcode)
  62. {
  63. Fcb *fcb;
  64. int dat_fd = -1;
  65. int ind_fd = -1;
  66. int var_fd = -1;
  67. int oldumask = umask (u_mask); /* Change umask to client's */
  68. /*
  69. * Create the UNIX file for .rec file.
  70. */
  71. if (crdat && (dat_fd = _create_datfile (isfname)) == -1) {
  72. _amseterrcode(errcode, errno);
  73. goto ERROR;
  74. }
  75. /*
  76. * If a primary is specified, create .ind file.
  77. */
  78. if (crind && (ind_fd = _create_indfile (isfname)) == -1) {
  79. _amseterrcode(errcode, errno);
  80. goto ERROR;
  81. }
  82. /*
  83. * If the ISAM file is for variable length records, create .var file.
  84. */
  85. if (crvar && (var_fd = _create_varfile (isfname)) == -1) {
  86. _amseterrcode(errcode, errno);
  87. goto ERROR;
  88. }
  89. /*
  90. * Change user and group onwer ship of the file.
  91. * This has affect only when executed by the netisamd daemon.
  92. */
  93. if (dat_fd != -1)
  94. (void) fchown(dat_fd, owner, group);
  95. if (ind_fd != -1)
  96. (void) fchown(ind_fd, owner, group);
  97. if (var_fd != -1)
  98. (void) fchown(var_fd, owner, group);
  99. /*
  100. * Allocate File Control Block.
  101. */
  102. fcb = (Fcb *) _ismalloc(sizeof(*fcb));
  103. memset ((char *) fcb, 0, sizeof(*fcb));
  104. fcb->isfname = _isallocstring(isfname);
  105. fcb->rdonly = FALSE;
  106. fcb->datfd = dat_fd;
  107. fcb->indfd = ind_fd;
  108. fcb->varfd = var_fd;
  109. fcb->datsize = N_CNTL_PAGES; /* Control Pages */
  110. fcb->indfreelist = FREELIST_NOPAGE;
  111. /* Key descriptor */
  112. fcb->nkeys = 1;
  113. fcb->keys = (Keydesc2 *) _ismalloc(sizeof(fcb->keys[0]));
  114. memset((char *)fcb->keys, 0, sizeof(fcb->keys[0]));
  115. return (fcb);
  116. ERROR:
  117. /* Undo whatever was done. */
  118. if (dat_fd != -1) {
  119. (void) close(dat_fd);
  120. _remove_datfile(isfname);
  121. }
  122. if (ind_fd != -1) {
  123. (void) close(ind_fd);
  124. _remove_indfile(isfname);
  125. }
  126. if (var_fd != -1) {
  127. (void) close(var_fd);
  128. _remove_varfile(isfname);
  129. }
  130. (void) umask(oldumask);
  131. return (NULL);
  132. }
  133. /*
  134. * _isfcb_setlength(fcb, varflag, minreclen, maxreclen)
  135. *
  136. * Set FCB attributes pertaining to record length.
  137. */
  138. void
  139. _isfcb_setreclength(Fcb *fcb, Bool varflag, int minreclen, int maxreclen)
  140. {
  141. fcb->varflag = varflag;
  142. fcb->minreclen = minreclen;
  143. fcb->maxreclen = maxreclen;
  144. }
  145. /*
  146. * _isfcb_open(isfname, errcode)
  147. *
  148. * Open ISAM file: open UNIX files and create File Control Block.
  149. *
  150. * Return 0 if open is successful, or -1 if any error. In the case of an error,
  151. * the errcode block is set.
  152. *
  153. * Note that rdonly is not fuly implemented. Now, all ISAM files are assumed
  154. * to have permissions set to 0666 and may be opened in RW mode.
  155. * If read-only media are used then the _open_datfile() function would have to
  156. * try first to open the file in RW mode, and of that failed, try to
  157. * open it in RO mode. The rdonly flag is used to reject any isamopen() with
  158. * INOUT or OUTPUT mode on such files.
  159. */
  160. Fcb *
  161. _isfcb_open(char *isfname, struct errcode *errcode)
  162. {
  163. Fcb *fcb;
  164. int dat_fd = -1;
  165. int ind_fd = -1;
  166. int var_fd = -1;
  167. Bool rdonly; /* set to 1 if file is Read-Only */
  168. /*
  169. * Open the UNIX file for .rec file.
  170. */
  171. if ((dat_fd = _open_datfile (isfname, &rdonly)) == -1 || errno == EMFILE) {
  172. _amseterrcode(errcode, errno);
  173. if(dat_fd != -1) {
  174. close(dat_fd);
  175. }
  176. return (NULL);
  177. }
  178. /*
  179. * Open .ind file.
  180. */
  181. ind_fd = _open_indfile (isfname, rdonly);
  182. /*
  183. * Open .var file.
  184. */
  185. var_fd = _open_varfile (isfname, rdonly);
  186. /*
  187. * Allocate File Control Block.
  188. */
  189. fcb = (Fcb *) _ismalloc(sizeof(*fcb));
  190. memset ((char *) fcb, 0, sizeof(*fcb));
  191. fcb->isfname = _isallocstring(isfname);
  192. fcb->rdonly = rdonly;
  193. fcb->datfd = dat_fd;
  194. fcb->indfd = ind_fd;
  195. fcb->varfd = var_fd;
  196. /* Key descriptor */
  197. fcb->nkeys = 1;
  198. fcb->keys = (Keydesc2 *) _ismalloc(sizeof(fcb->keys[0]));
  199. memset((char *)fcb->keys, 0, sizeof(fcb->keys[0]));
  200. return (fcb);
  201. }
  202. /*
  203. * _isfcb_nfds(fcb)
  204. *
  205. * Return the number of UNIX fd consumed by the fcb block.
  206. */
  207. int
  208. _isfcb_nfds(Fcb *fcb)
  209. {
  210. int count = 0;
  211. if (fcb->datfd != -1)
  212. count++;
  213. if (fcb->indfd != -1)
  214. count++;
  215. if (fcb->varfd != -1)
  216. count++;
  217. return (count);
  218. }
  219. /*
  220. * _isfcb_remove(fcb)
  221. *
  222. * Remove UNIX files associated with an FCB.
  223. */
  224. void
  225. _isfcb_remove(Fcb *fcb)
  226. {
  227. if (fcb->datfd)
  228. _remove_datfile(fcb->isfname);
  229. if (fcb->indfd)
  230. _remove_indfile(fcb->isfname);
  231. if (fcb->varfd)
  232. _remove_varfile(fcb->isfname);
  233. }
  234. /*
  235. * _isfcb_close(fcb)
  236. *
  237. * Close UNIX files associated with an FCB, deallocate the FCB block.
  238. */
  239. void
  240. _isfcb_close(Fcb *fcb)
  241. {
  242. assert (fcb != NULL);
  243. assert (fcb->isfname != NULL);
  244. (void) close(fcb->datfd);
  245. (void) close(fcb->indfd);
  246. (void) close(fcb->varfd);
  247. _isfreestring(fcb->isfname);
  248. free((char *)fcb->keys);
  249. free((char *)fcb);
  250. }
  251. /*
  252. * _isfcb_cntlpg_w(fcb)
  253. *
  254. * Write information from the control block to the disk.
  255. * Note that the Control Page transfer bypasses the disk buffer manager.
  256. *
  257. * Return 0 if write was successful, return -1 if any error.
  258. */
  259. int
  260. _isfcb_cntlpg_w(Fcb *fcb)
  261. {
  262. char cntl_page[ISCNTLSIZE];
  263. int dat_fd = fcb->datfd;
  264. int i;
  265. /* Clear the page. */
  266. memset (cntl_page, 0, sizeof(cntl_page));
  267. /* Set Magic number. */
  268. (void)strcpy(cntl_page + CP_MAGIC_OFF, ISMAGIC);
  269. /* Set Block size */
  270. stshort(ISPAGESIZE, cntl_page + CP_BLOCKSIZE_OFF);
  271. /* Set NetISAM version stamp. */
  272. (void)strcpy(cntl_page + CP_VERSION_OFF, ISVERSION);
  273. /* .rec file size in blocks. */
  274. stlong((long)fcb->datsize, cntl_page + CP_DATSIZE_OFF);
  275. /* .ind file size in blocks. */
  276. stlong((long)fcb->indsize, cntl_page + CP_INDSIZE_OFF);
  277. /* .var file size in blocks. */
  278. stlong((long)fcb->varsize, cntl_page + CP_VARSIZE_OFF);
  279. /* Variable length 0/1 flag. */
  280. stshort((short)fcb->varflag, cntl_page + CP_VARFLAG_OFF);
  281. /* Number of records. */
  282. stlong((long)fcb->nrecords, cntl_page + CP_NRECORDS_OFF);
  283. /* Minimum and maximum record length. */
  284. stshort((short)fcb->minreclen, cntl_page + CP_MINRECLEN_OFF);
  285. stshort((short)fcb->maxreclen, cntl_page + CP_MAXRECLEN_OFF);
  286. /* Last record number. */
  287. strecno(fcb->lastrecno, cntl_page + CP_LASTRECNO_OFF);
  288. /* Free record number. */
  289. strecno(fcb->freerecno, cntl_page + CP_FREERECNO_OFF);
  290. /* Number of keys */
  291. stshort((short)fcb->nkeys, cntl_page + CP_NKEYS_OFF);
  292. /* Last key id */
  293. stlong((long)fcb->lastkeyid, cntl_page + CP_LASTKEYID_OFF);
  294. /* ind. free list head */
  295. stlong((long)fcb->indfreelist, cntl_page + CP_INDFREELIST_OFF);
  296. /* offset of the end of .var file */
  297. stlong((long)fcb->varend, cntl_page + CP_VAREND_OFF);
  298. /* Key descriptors. */
  299. for (i = 0; i < fcb->nkeys; i++) {
  300. stkey(fcb->keys + i, cntl_page + CP_KEYS_OFF + i * K2_LEN);
  301. }
  302. /* Increment stamp1 and stamp2 to indicate change in the Control Page. */
  303. fcb->changestamp1++;
  304. fcb->changestamp2++;
  305. stlong((long)fcb->changestamp1, cntl_page + CP_CHANGESTAMP1_OFF);
  306. stlong((long)fcb->changestamp2, cntl_page + CP_CHANGESTAMP2_OFF);
  307. /*
  308. * Write the buffer to the disk.
  309. */
  310. _isseekpg(dat_fd, ISCNTLPGOFF);
  311. _iswritepg(dat_fd, cntl_page);
  312. _iswritepg(dat_fd, cntl_page + ISPAGESIZE);
  313. return (ISOK);
  314. }
  315. /*
  316. * _isfcb_cntlpg_w2(fcb)
  317. *
  318. * Write information from the control block to the disk.
  319. * Write only selected fields of the control block to avoid the overhead
  320. * of coding and decoding.
  321. * Note that the Control Page transfer bypasses the disk buffer manager.
  322. *
  323. * Return 0 if write was successful, return -1 if any error.
  324. */
  325. int
  326. _isfcb_cntlpg_w2(Fcb *fcb)
  327. {
  328. char cntl_page[CP_VAREND_OFF+CP_VAREND_LEN];
  329. int dat_fd = fcb->datfd;
  330. /*
  331. * Read the page from disk.
  332. */
  333. _isseekpg(dat_fd, ISCNTLPGOFF);
  334. (void)read(dat_fd, cntl_page, sizeof(cntl_page));
  335. /* .rec file size in blocks. */
  336. stlong((long)fcb->datsize, cntl_page + CP_DATSIZE_OFF);
  337. /* .ind file size in blocks. */
  338. stlong((long)fcb->indsize, cntl_page + CP_INDSIZE_OFF);
  339. /* .var file size in blocks. */
  340. stlong((long)fcb->varsize, cntl_page + CP_VARSIZE_OFF);
  341. /* Number of records. */
  342. stlong((long)fcb->nrecords, cntl_page + CP_NRECORDS_OFF);
  343. /* Last record number. */
  344. strecno(fcb->lastrecno, cntl_page + CP_LASTRECNO_OFF);
  345. /* Free record number. */
  346. strecno(fcb->freerecno, cntl_page + CP_FREERECNO_OFF);
  347. /* ind. free list head */
  348. stlong((long)fcb->indfreelist, cntl_page + CP_INDFREELIST_OFF);
  349. /* end of .var file */
  350. stlong((long)fcb->varend, cntl_page + CP_VAREND_OFF);
  351. /* Increment stamp2 to indicate change in the Control Page. */
  352. fcb->changestamp2++;
  353. stlong((long)fcb->changestamp2, cntl_page + CP_CHANGESTAMP2_OFF);
  354. /*
  355. * Write the buffer to the disk.
  356. */
  357. _isseekpg(dat_fd, ISCNTLPGOFF);
  358. (void)write(dat_fd, cntl_page, sizeof(cntl_page));
  359. return (ISOK);
  360. }
  361. /*
  362. * _isfcb_cntlpg_r(fcb)
  363. *
  364. * Read information from control page and store it in the FCB.
  365. * Note that the Control Page transfer bypasses the disk buffer manager.
  366. *
  367. * Return 0 if read was successful, return -1 if any error.
  368. */
  369. int
  370. _isfcb_cntlpg_r(Fcb *fcb)
  371. {
  372. char cntl_page[ISCNTLSIZE];
  373. int dat_fd = fcb->datfd;
  374. int i;
  375. /*
  376. * Read the page from the disk.
  377. */
  378. _isseekpg(dat_fd, ISCNTLPGOFF);
  379. _isreadpg(dat_fd, cntl_page);
  380. _isreadpg(dat_fd, cntl_page + ISPAGESIZE);
  381. /* block size */
  382. fcb->blocksize = ldshort(cntl_page + CP_BLOCKSIZE_OFF);
  383. /* .rec file size in blocks. */
  384. fcb->datsize = ldlong(cntl_page + CP_DATSIZE_OFF);
  385. /* .ind file size in blocks. */
  386. fcb->indsize = ldlong(cntl_page + CP_INDSIZE_OFF);
  387. /* .var file size in blocks. */
  388. fcb->varsize = ldlong(cntl_page + CP_VARSIZE_OFF);
  389. /* Variable length 0/1 flag. */
  390. fcb->varflag = (Bool)ldshort(cntl_page + CP_VARFLAG_OFF);
  391. /* Number of records. */
  392. fcb->nrecords = ldlong(cntl_page + CP_NRECORDS_OFF);
  393. /* Minimum and maximum record length. */
  394. fcb->minreclen = ldunshort(cntl_page + CP_MINRECLEN_OFF);
  395. fcb->maxreclen = ldunshort(cntl_page + CP_MAXRECLEN_OFF);
  396. /* Last record number. */
  397. fcb->lastrecno = ldrecno(cntl_page + CP_LASTRECNO_OFF);
  398. /* Free record number. */
  399. fcb->freerecno = ldrecno(cntl_page + CP_FREERECNO_OFF);
  400. /* Last key id */
  401. fcb->lastkeyid = ldlong(cntl_page + CP_LASTKEYID_OFF);
  402. /* .ind free list head. */
  403. fcb->indfreelist = ldlong(cntl_page + CP_INDFREELIST_OFF);
  404. /* end of .var file */
  405. fcb->varend = ldlong(cntl_page + CP_VAREND_OFF);
  406. /* Number of keys */
  407. fcb->nkeys = ldshort(cntl_page + CP_NKEYS_OFF);
  408. /*
  409. * Read key descriptors.
  410. */
  411. fcb->keys = (Keydesc2 *)
  412. _isrealloc((char *)fcb->keys,
  413. (unsigned) (sizeof(Keydesc2) * fcb->nkeys));
  414. memset((char *)fcb->keys, 0, sizeof(Keydesc2) * fcb->nkeys);
  415. for (i = 0; i < fcb->nkeys; i++) {
  416. ldkey(fcb->keys + i, cntl_page + CP_KEYS_OFF + i * K2_LEN);
  417. }
  418. /* Changestamp1 */
  419. fcb->changestamp1 = ldlong(cntl_page + CP_CHANGESTAMP1_OFF);
  420. /* Changestamp2 */
  421. fcb->changestamp2 = ldlong(cntl_page + CP_CHANGESTAMP2_OFF);
  422. /*
  423. * Open .ind file in situations when some other process has created
  424. * keys and this process has just learned it now.
  425. */
  426. if (fcb->nkeys > 1 || !FCB_NOPRIMARY_KEY(fcb)) {
  427. /*
  428. if (_open2_indfile(fcb) != ISOK)
  429. _isfatal_error("_open2_indfile()");
  430. */
  431. (void)_open2_indfile(fcb);
  432. }
  433. return (ISOK);
  434. }
  435. /*
  436. * _isfcb_cntlpg_r2(fcb)
  437. *
  438. * Read information from the control block on the disk.
  439. * Read only selected fields of the control block to avoid the overhead
  440. * of coding and decoding.
  441. * Note that the Control Page transfer bypasses the disk buffer manager.
  442. *
  443. * Return 0 if write was successful, return -1 if any error.
  444. */
  445. int
  446. _isfcb_cntlpg_r2(Fcb *fcb)
  447. {
  448. char cntl_page[CP_VAREND_OFF+CP_VAREND_LEN];
  449. int dat_fd = fcb->datfd;
  450. /*
  451. * Read the page from disk.
  452. */
  453. _isseekpg(dat_fd, ISCNTLPGOFF);
  454. (void)read(dat_fd, cntl_page, sizeof(cntl_page));
  455. /*
  456. * Check changestamp1. If the stamp has changed, we must read the entire
  457. * page and update the FCB.
  458. */
  459. if (ldlong(cntl_page + CP_CHANGESTAMP1_OFF) != fcb->changestamp1) {
  460. (void)_isfcb_cntlpg_r(fcb);
  461. }
  462. /*
  463. *_isfcb_cntlpg_r2() is called if transaction is rolled back.
  464. * We cannot test changestamp2; we must read the info into the FCB
  465. * always.
  466. */
  467. #if 0
  468. /*
  469. * Check changestamp2. If the stamp has not changed, the FCB contains
  470. * up-to-date information.
  471. */
  472. if (ldlong(cntl_page + CP_CHANGESTAMP2_OFF) == fcb->changestamp2) {
  473. return (ISOK);
  474. }
  475. #endif
  476. /* .rec file size in blocks. */
  477. fcb->datsize = ldlong(cntl_page + CP_DATSIZE_OFF);
  478. /* .ind file size in blocks. */
  479. fcb->indsize = ldlong(cntl_page + CP_INDSIZE_OFF);
  480. /* .var file size in blocks. */
  481. fcb->varsize = ldlong(cntl_page + CP_VARSIZE_OFF);
  482. /* Number of records. */
  483. fcb->nrecords = ldlong(cntl_page + CP_NRECORDS_OFF);
  484. /* Last record number. */
  485. fcb->lastrecno = ldrecno(cntl_page + CP_LASTRECNO_OFF);
  486. /* Free record number. */
  487. fcb->freerecno = ldrecno(cntl_page + CP_FREERECNO_OFF);
  488. /* .ind free list head. */
  489. fcb->indfreelist = ldlong(cntl_page + CP_INDFREELIST_OFF);
  490. /* end of .var file */
  491. fcb->varend = ldlong(cntl_page + CP_VAREND_OFF);
  492. /* Changestamp2 */
  493. fcb->changestamp2 = ldlong(cntl_page + CP_CHANGESTAMP2_OFF);
  494. return (ISOK);
  495. }
  496. /*
  497. * _create_datfile(isfname)
  498. *
  499. * Create .rec file for ISAM file isfname.
  500. */
  501. Static int
  502. _create_datfile(char *isfname)
  503. {
  504. int fd;
  505. char namebuf[MAXPATHLEN];
  506. snprintf(namebuf, sizeof(namebuf), "%s", isfname);
  507. _makedat_isfname(namebuf);
  508. fd = open (namebuf, O_CREAT | O_EXCL | O_RDWR, 0666);
  509. if (fd > -1) {
  510. /* Close on exec */
  511. if(fcntl(fd, F_SETFD, 1) == -1) {
  512. close(fd);
  513. return(-1);
  514. }
  515. }
  516. return (fd);
  517. }
  518. /*
  519. * _create_indfile(isfname)
  520. *
  521. * Create .ind file for ISAM file isfname.
  522. */
  523. Static int
  524. _create_indfile(char *isfname)
  525. {
  526. int fd;
  527. char namebuf[MAXPATHLEN];
  528. snprintf(namebuf, sizeof(namebuf), "%s", isfname);
  529. _makeind_isfname(namebuf);
  530. fd = open (namebuf, O_CREAT | O_EXCL | O_RDWR, 0666);
  531. if (fd > -1) {
  532. /* Close on exec */
  533. if(fcntl(fd, F_SETFD, 1) == -1) {
  534. close(fd);
  535. return(-1);
  536. }
  537. }
  538. return (fd);
  539. }
  540. /*
  541. * _create_varfile(isfname)
  542. *
  543. * Create .var file for ISAM file isfname.
  544. */
  545. Static int
  546. _create_varfile(char *isfname)
  547. {
  548. int fd;
  549. char namebuf[MAXPATHLEN];
  550. snprintf(namebuf, sizeof(namebuf), "%s", isfname);
  551. _makevar_isfname(namebuf);
  552. fd = open (namebuf, O_CREAT | O_EXCL | O_RDWR, 0666);
  553. if (fd > -1) {
  554. /* Close on exec */
  555. if(fcntl(fd, F_SETFD, 1) == -1) {
  556. close(fd);
  557. return(-1);
  558. }
  559. }
  560. return (fd);
  561. }
  562. /*
  563. * _remove_datfile(isfname)
  564. *
  565. * Remove .rec file for ISAM file isfname.
  566. */
  567. Static void
  568. _remove_datfile(char *isfname)
  569. {
  570. char namebuf[MAXPATHLEN];
  571. snprintf(namebuf, sizeof(namebuf), "%s", isfname);
  572. _makedat_isfname(namebuf);
  573. (void) unlink(namebuf);
  574. }
  575. /*
  576. * _remove_indfile(isfname)
  577. *
  578. * Remove .ind file for ISAM file isfname.
  579. */
  580. Static void
  581. _remove_indfile(char *isfname)
  582. {
  583. char namebuf[MAXPATHLEN];
  584. snprintf(namebuf, sizeof(namebuf), "%s", isfname);
  585. _makeind_isfname(namebuf);
  586. (void) unlink(namebuf);
  587. }
  588. /*
  589. * _remove_varfile(isfname)
  590. *
  591. * Remove .var file for ISAM file isfname.
  592. */
  593. Static void
  594. _remove_varfile(char *isfname)
  595. {
  596. char namebuf[MAXPATHLEN];
  597. snprintf(namebuf, sizeof(namebuf), "%s", isfname);
  598. _makevar_isfname(namebuf);
  599. (void) unlink(namebuf);
  600. }
  601. /*
  602. * _open_datfile(isfname)
  603. *
  604. * Open .rec file for ISAM file isfname.
  605. */
  606. Static int
  607. _open_datfile(char *isfname, Bool *rdonly)
  608. {
  609. char namebuf[MAXPATHLEN];
  610. int ret;
  611. snprintf(namebuf, sizeof(namebuf), "%s", isfname);
  612. _makedat_isfname(namebuf);
  613. if ((ret = open (namebuf, O_RDWR)) != -1) {
  614. *rdonly = FALSE;
  615. /* Close on exec */
  616. if(fcntl(ret, F_SETFD, 1) == -1) {
  617. close(ret);
  618. ret = -1;
  619. }
  620. return (ret);
  621. }
  622. *rdonly = TRUE;
  623. ret = open (namebuf, O_RDONLY);
  624. if (ret > -1) {
  625. /* Close on exec */
  626. if(fcntl(ret, F_SETFD, 1) == -1) {
  627. close(ret);
  628. return(-1);
  629. }
  630. }
  631. return (ret);
  632. }
  633. /*
  634. * _open_indfile(isfname)
  635. *
  636. * Open .ind file for ISAM file isfname.
  637. */
  638. Static int
  639. _open_indfile(char *isfname, Bool rdonly)
  640. {
  641. int fd;
  642. char namebuf[MAXPATHLEN];
  643. snprintf(namebuf, sizeof(namebuf), "%s", isfname);
  644. _makeind_isfname(namebuf);
  645. fd = open (namebuf, (rdonly==TRUE)?O_RDONLY:O_RDWR);
  646. if (fd > -1) {
  647. /* Close on exec */
  648. if(fcntl(fd, F_SETFD, 1) == -1) {
  649. close(fd);
  650. return(-1);
  651. }
  652. }
  653. return (fd);
  654. }
  655. /*
  656. * _open_varfile(isfname)
  657. *
  658. * Open .var file for ISAM file isfname.
  659. */
  660. Static int
  661. _open_varfile(char *isfname, Bool rdonly)
  662. {
  663. int fd;
  664. char namebuf[MAXPATHLEN];
  665. snprintf(namebuf, sizeof(namebuf), "%s", isfname);
  666. _makevar_isfname(namebuf);
  667. fd = open (namebuf, (rdonly==TRUE)?O_RDONLY:O_RDWR);
  668. if (fd > -1) {
  669. /* Close on exec */
  670. if(fcntl(fd, F_SETFD, 1) == -1) {
  671. close(fd);
  672. return(-1);
  673. }
  674. }
  675. return (fd);
  676. }
  677. int
  678. _check_isam_magic(Fcb *fcb)
  679. {
  680. char magicbuffer[CP_MAGIC_LEN];
  681. (void)lseek(fcb->datfd, 0L, 0);
  682. if ((read(fcb->datfd, magicbuffer, CP_MAGIC_LEN) < CP_MAGIC_LEN) ||
  683. /* The following test for compatibilty with `SunISAM 1.0 Beta files. */
  684. ((strncmp(magicbuffer, "SunISAM", strlen(ISMAGIC)) != 0) &&
  685. (strncmp(magicbuffer, ISMAGIC, strlen(ISMAGIC))) != 0)) {
  686. return ISERROR;
  687. }
  688. else
  689. return ISOK;
  690. }
  691. /*
  692. * _open2_indfile(fcb)
  693. *
  694. * Open (or create) .ind file for ISAM file if the .ind file
  695. * is not open already (or does not exist).
  696. */
  697. int
  698. _open2_indfile(Fcb *fcb)
  699. {
  700. char namebuf[MAXPATHLEN];
  701. struct stat buf;
  702. int openmode;
  703. if (fcb->indfd != -1)
  704. return (ISOK);
  705. snprintf(namebuf, sizeof(namebuf), "%s", fcb->isfname);
  706. _makeind_isfname(namebuf);
  707. (void)fstat(fcb->datfd, &buf);
  708. openmode = (fcb->rdonly) ? O_RDONLY : O_RDWR;
  709. if (fcb->indsize == 0)
  710. openmode |= O_CREAT;
  711. fcb->indfd = open(namebuf, openmode, buf.st_mode);
  712. if (fcb->indfd > -1) {
  713. /* Close on exec */
  714. if(fcntl(fcb->indfd, F_SETFD, 1) == -1) {
  715. close(fcb->indfd);
  716. fcb->indfd = -1;
  717. }
  718. }
  719. if(fcb->indfd == -1 && (openmode & O_CREAT)) {
  720. _isfatal_error("Cannot create .ind file");
  721. }
  722. if (fcb->indfd != -1) {
  723. (void) _watchfd_incr(1);
  724. (void)fchown(fcb->indfd, buf.st_uid, buf.st_gid);
  725. }
  726. return ((fcb->indfd == -1) ? ISERROR : ISOK);
  727. }