097422cbbc88e1a393301663e7e79ffabc5da3e1
[oweals/cde.git] / cde / lib / DtSearch / raima / reclast.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 librararies 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: reclast.c /main/2 1996/05/09 04:14:30 drk $ */
24 /*
25  *   COMPONENT_NAME: austext
26  *
27  *   FUNCTIONS: d_reclast
28  *
29  *   ORIGINS: 157
30  *
31  *   OBJECT CODE ONLY SOURCE MATERIALS
32  */
33 /*-----------------------------------------------------------------------
34
35    reclast.c - find last record occurance in database
36
37    reclast is used to setup a scan of a database by database number
38    backwards, and is complementary to recfrst.
39
40    AUTHOR:  R.S. Carlson
41    DATE:    06-Jul-88
42    PROJECT: db_VISTA 3.10
43
44    Copyright (C) 1988 by Raima Corporation
45
46 -----------------------------------------------------------------------*/
47
48 /* ********************** EDIT HISTORY *******************************
49
50  SCR    DATE    INI                   DESCRIPTION
51 ----- --------- --- -----------------------------------------------------
52   351 06-Jul-88 RSC new function added to runtime
53       04-Aug-88 RTK MULTI_TASK changes
54       09-Aug-88 RSC rno-- needs to be outside ifndef SINGLE_USER
55       18-Aug-88 RSC moved rn_type/dba to separate table
56
57 */
58
59
60 /* ********************** INCLUDE FILES ****************************** */
61
62 #include <stdio.h>
63 #include "vista.h"
64 #include "dbtype.h"
65
66 /* ********************** GLOBAL VARIABLE DECLARATIONS *************** */
67 /* ********************** GLOBAL FUNCTION DECLARATIONS *************** */
68 /* ********************** EXTERNAL VARIABLE DECLARATIONS ************* */
69 /* ********************** EXTERNAL FUNCTION DECLARATIONS ************* */
70 /* ********************** LOCAL VARIABLE DECLARATIONS **************** */
71 /* ********************** LOCAL FUNCTION DECLARATIONS **************** */
72
73 /* ======================================================================
74    d_reclast - find last record occurance in database
75 */
76 int d_reclast( rec TASK_PARM DBN_PARM )
77 int rec;                        /* record # to find last occurance of */
78 TASK_DECL
79 DBN_DECL                        /* optional database number */
80 {
81 /*
82    RETURNS: db_status.  Sets current record to last record, if found.
83    ASSUMES: nothing.
84 */
85    DB_ADDR dba;                 /* current database addr we're scanning */
86    FILE_NO ftype;               /* file desc for file holding rec */
87    F_ADDR last;                 /* last slot in file */
88    char FAR *recptr;            /* record from database */
89    RECORD_ENTRY FAR *rec_ptr;   /* RECORD ENTRY for this record */
90    INT rectype;                 /* record type from record */
91    F_ADDR rno;                  /* current slot we're scanning */
92
93 #ifndef SINGLE_USER
94    int dbopen_sv;               /* saved copy of dbopen */
95 #endif
96
97    DB_ENTER(DB_ID TASK_ID LOCK_SET(RECORD_IO));
98
99    /* validate and convert record number */
100    if ( nrec_check(rec, &rec, (RECORD_ENTRY FAR * FAR *)&rec_ptr) != S_OKAY)
101       RETURN( db_status );
102
103    /* get the last record # for this file */
104    ftype = NUM2EXT(rec_ptr->rt_file, ft_offset);
105    if ( (last = dio_pznext(rec_ptr->rt_file)) <= 0 )
106       RETURN( db_status );
107
108    /* start at the end, working backwards, find a matching record */
109    rno = last - 1;
110    do {
111       if ( rno < 1)
112          RETURN ( db_status = S_NOTFOUND );
113       
114       /* create the database address, and read this record */
115       dba = ((FILEMASK & ftype) << FILESHIFT) | (ADDRMASK & rno);
116 #ifndef SINGLE_USER
117       dbopen_sv = dbopen;
118       dbopen = 2;               /* setup to allow unlocked read */
119 #endif
120       dio_read(dba, (char FAR * FAR *)&recptr, NOPGHOLD);
121 #ifndef SINGLE_USER
122       dbopen = dbopen_sv;
123 #endif
124       if ( db_status != S_OKAY )
125          RETURN( db_status );
126       
127       /* See if this record is of the type we're looking for */
128       bytecpy(&rectype, recptr, sizeof(INT));
129 #ifndef SINGLE_USER
130       rectype &= ~((INT)RLBMASK);       /* remove rlb */
131 #endif
132       rno--;
133    } while ( (int)rectype != rec );
134
135    /* when we get here, we know a match was found */
136    curr_rec = dba;                      /* set current record */
137    RN_REF(rn_type) = rectype;           /* setup for future recprev,recnext */
138    RN_REF(rn_dba) = dba;
139    RETURN( db_status = S_OKAY );
140 }
141 /* vpp -nOS2 -dUNIX -nBSD -nVANILLA_BSD -nVMS -nMEMLOCK -nWINDOWS -nFAR_ALLOC -f/usr/users/master/config/nonwin reclast.c */