Fixes for OpenBSD
[oweals/cde.git] / cde / lib / DtSearch / raima / initial.c
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 /* $XConsortium: initial.c /main/3 1996/08/12 12:34:00 cde-ibm $ */
24 /*
25  *   COMPONENT_NAME: austext
26  *
27  *   FUNCTIONS: d_initfile
28  *              d_initialize
29  *
30  *   ORIGINS: 157
31  *
32  *   OBJECT CODE ONLY SOURCE MATERIALS
33  */
34 /*-----------------------------------------------------------------------
35    initial.c -- db_VISTA database initialization module.
36
37    (C) Copyright 1987 by Raima Corporation.
38 -----------------------------------------------------------------------*/
39
40 /* ********************** EDIT HISTORY *******************************
41
42  SCR    DATE    INI                   DESCRIPTION
43 ----- --------- --- -----------------------------------------------------
44   295 01-Jul-88 RSC d_initialize/d_initfile can corrupt disk
45   115 19-Jul-88 RSC Integrate VAX/VMS changes into code
46   365 25-Jul-88 RSC Add dbn argument to d_initialize
47   368 28-Jul-88 RSC Integrate BSD changes into code
48       04-Aug-88 RTK MULTI_TASK changes
49   115 16-Aug-88 RSC Fixup of VMS integration
50 */
51
52 #include <stdio.h>
53 #include <fcntl.h>
54 #include "vista.h"
55 #include "dbtype.h"
56 #include "dbswab.h"
57
58 #define LENVDBID 48
59
60 typedef union INIT_PAGE_U {
61    struct {
62       F_ADDR  dchain;              /* delete chain pointer */
63       F_ADDR  next;                /* next page or record slot */
64       LONG    timestamp;           /* file's timestamp value */
65       LONG    cdate;               /* creation date,time */
66       LONG    bdate;               /* date/time of last backup */
67       char vdb_id[LENVDBID];       /* db_vista id mark */
68    } pg0;
69    struct {
70       LONG  chg_date;              /* date of last page change */
71       char  init_int[sizeof(INT)];  /* # filled slots on key file;
72                                       System record # on data file */
73       char  init_addr[sizeof(LONG)];  /* NONE node pointer on key file;
74                                       System record db_addr on data file */
75       char  init_crts[sizeof(LONG)];  /* if system record is timestamped */
76       char  init_upts[sizeof(LONG)];  /* if system record is timestamped */
77    } pg1;
78 } INIT_PAGE;
79
80 typedef struct {union INIT_PAGE_U FAR *ptr; LOCK_DESC} INIT_PAGE_P;
81
82 static char nulls[5] = "\0\0\0\0";
83 static int dbfile;
84 extern int cnt_open_files;              /* see dio.c */
85 extern int max_open_files;              /* see dio.c */
86
87
88 /* Database initialization function
89 */
90 int
91 d_initialize(TASK_DBN_ONLY)
92 TASK_DECL
93 DBN_DECL
94 {
95    FILE_NO fno;
96
97    DB_ENTER(DB_ID TASK_ID LOCK_SET(RECORD_IO));
98
99    if (dbopen != 2)
100       dberr(S_EXCLUSIVE);
101    else {
102       /* initialize db files in file_table */
103       for (fno = 0; fno < DB_REF(Size_ft); ++fno) {
104          if ( d_initfile(fno TASK_PARM DBN_PARM) != S_OKAY )
105             break;
106       }
107    }
108    RETURN( db_status );
109 }
110
111
112
113 /* Initialize database file
114 */
115 int
116 d_initfile(fno TASK_PARM DBN_PARM)
117 FILE_NO fno; /* file table entry of file to be initialized */
118 TASK_DECL
119 DBN_DECL
120 {
121    INIT_PAGE_P Page;
122 #define page (Page.ptr)
123    F_ADDR addr;
124    ULONG ts;
125    INT rno, rec;
126    FILE_ENTRY FAR *file_ptr;
127    RECORD_ENTRY FAR *rec_ptr;
128    time_t       local_timestamp;
129    LONG         extern_timestamp;
130
131    DB_ENTER(DB_ID TASK_ID LOCK_SET(RECORD_IO));
132
133    if ( dbopen != 2 )
134       RETURN( dberr(S_EXCLUSIVE) );
135
136    time (&local_timestamp);
137    extern_timestamp = htonl ((LONG) local_timestamp);
138
139 #ifndef  ONE_DB
140    fno += curr_db_table->ft_offset;
141 #endif
142    file_ptr = &file_table[fno];
143
144    /* If file is open - close it */
145    if (file_ptr->ft_status == OPEN) dio_close(fno);
146    else if (cnt_open_files == max_open_files) {
147       /* We don't have enuf files, open then close this file to free one */
148       dio_open(fno);
149       dio_close(fno);
150    }
151    dio_clrfile(fno);                    /* clear file's pages */
152
153    if ((dbfile = DB_OPEN(file_ptr->ft_name, O_RDWR | O_CREAT | O_TRUNC)) < 0)
154       RETURN( dberr(S_NOFILE) );
155    
156    page = (INIT_PAGE FAR *)ALLOC(&Page, file_ptr->ft_pgsize, "page");
157    if ( page == NULL ) RETURN( dberr(S_NOMEMORY) );
158
159    /*--------- Init PAGE 0 ---------*/
160    byteset(page, '\0', file_ptr->ft_pgsize);
161    /**time(&page->pg0.cdate);***/
162    page->pg0.cdate =            extern_timestamp;
163    strcpy(page->pg0.vdb_id,     "db_VISTA Version ");
164    strcat(page->pg0.vdb_id,     db_VERSION);
165    page->pg0.bdate =            0;
166    if (file_ptr->ft_type == KEY) {
167       /*--------- Write KEY FILE PAGE 0 ---------*/
168       page->pg0.dchain =        htonl ((LONG) NONE);
169       page->pg0.next =          htonl (2);
170       page->pg0.timestamp =     0; /* not really used by key file */
171       DB_WRITE(dbfile, (char FAR *)page, (int)file_ptr->ft_pgsize);
172
173       /*--------- Write KEY FILE PAGE 1 ---------*/
174       byteset(page, '\0', file_ptr->ft_pgsize);
175       page->pg1.chg_date =      extern_timestamp;
176       /* node 1, current # of filled slots */
177       bytecpy(page->pg1.init_int, nulls, sizeof(INT));
178       /* node 1, NONE page pointer */
179       addr =                    -1;
180       bytecpy(page->pg1.init_addr, &addr, sizeof(F_ADDR));
181       DB_WRITE(dbfile, (char FAR *)page, (int)file_ptr->ft_pgsize);
182    }
183    else {
184       /*--------- Init DATA PAGE 0 ---------
185        * We'll write a page 0 and page 1 for the file (if any)
186        * with the system record, otherwise just a generic page 0.
187        */
188       page->pg0.dchain =        0;
189       page->pg0.timestamp =     htonl (1); 
190       /* check to see if this file contains a system record */
191       for (rec = 0, rec_ptr = record_table; rec < size_rt; ++rec, ++rec_ptr) {
192          if ((rec_ptr->rt_fdtot == -1) && (rec_ptr->rt_file == fno)) {
193
194             /*---Write special DATA FILE PAGE 0 for system record file ---*/
195             page->pg0.next =    htonl (2);
196             DB_WRITE(dbfile, (char FAR *)page, (int)file_ptr->ft_pgsize);
197
198             /*--------- Write DATA FILE PAGE 1 for system record ---------*/
199             byteset(page, '\0', file_ptr->ft_pgsize);
200             /* Data page header is current timestamp */
201             /*****time(&page->pg1.chg_date);****/
202             page->pg1.chg_date =        extern_timestamp;
203             addr =              (((LONG) NUM2EXT(fno, ft_offset) & FILEMASK)
204                                         << FILESHIFT) | 1;
205             HTONL (addr);
206             bytecpy(page->pg1.init_addr, &addr, sizeof(F_ADDR));
207
208             /* Slot 1 (system record) header is recid, dba,
209              * maybe two phony timestamps, no set ptrs or member ptrs.
210              */
211             rno =               htons (NUM2EXT(rec, rt_offset));
212             bytecpy(page->pg1.init_int, &rno, sizeof(INT));
213             if ( rec_ptr->rt_flags & TIMESTAMPED ) {
214                /* timestamp system record */
215                ts =             htonl (1);
216                bytecpy(page->pg1.init_crts, &ts, sizeof(ULONG));
217                bytecpy(page->pg1.init_upts, &ts, sizeof(ULONG));
218             }
219             DB_WRITE(dbfile, (char FAR *)page, (int)file_ptr->ft_pgsize);
220             break;
221          }
222       }
223       /*--------- Write generic DATA FILE PAGE 0 ---------
224        * If we went through whole record table without finding
225        * a system record, just write a generic page 0.
226        */
227       if (rec == size_rt) {
228          page->pg0.next =       htonl (1);
229          DB_WRITE(dbfile, (char FAR *)page, (int)file_ptr->ft_pgsize);
230       }
231    }
232    /* close database file */
233    DB_CLOSE(dbfile);
234    dio_pzread(fno);  /* re-read file header */
235    MEM_UNLOCK(&Page);
236    FREE(&Page);
237    RETURN( db_status );
238 }
239 /* vpp -nOS2 -dUNIX -nBSD -nVANILLA_BSD -nVMS -nMEMLOCK -nWINDOWS -nFAR_ALLOC -f/usr/users/master/config/nonwin initial.c */