2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $XConsortium: connect.c /main/2 1996/05/09 03:56:41 drk $ */
25 * COMPONENT_NAME: austext
33 * OBJECT CODE ONLY SOURCE MATERIALS
35 /*-----------------------------------------------------------------------
36 connect.c -- db_VISTA set connection module
38 (C) Copyright 1985, 1986, 1987 by Raima Corp.
39 -----------------------------------------------------------------------*/
41 /* ********************** EDIT HISTORY *******************************
43 SCR DATE INI DESCRIPTION
44 ----- --------- --- -----------------------------------------------------
45 04-Aug-88 RTK MULTI_TASK changes
52 /* Internal function Prototypes */
53 static int sortcmp(P1(SET_ENTRY FAR *) Pi(char FAR *)
56 /* set pointer structure definition */
58 LONG total; /* total number of members in set */
59 DB_ADDR first; /* database address of first member in set */
60 DB_ADDR last; /* database address of last member in set */
62 ULONG timestamp; /* set update timestamp - if used */
66 /* member pointer structure definition */
68 DB_ADDR owner; /* database address of owner record */
69 DB_ADDR prev; /* database address of previous member in set */
70 DB_ADDR next; /* database address of next member in set */
74 /* Connect the current record as member of set
77 d_connect(set TASK_PARM DBN_PARM)
78 int set; /* Set constant */
80 DBN_DECL /* Database number */
82 MEM_PTR crmp; /* current record's member pointer */
83 SET_PTR cosp; /* current owner's set pointer */
84 MEM_PTR cmmp; /* current member's member pointer */
85 MEM_PTR nmmp; /* next member's member pointer */
86 char FAR *crec; /* ptr to current record contents in cache */
87 char FAR *orec; /* ptr to current owner record contents in cache */
88 char FAR *mrec; /* ptr to current member record contents in cache */
89 char FAR *nrec; /* ptr to next member record contents in cache */
90 DB_ADDR mdba; /* db address of current member record */
91 DB_ADDR ndba; /* db address of next member record */
92 INT ordering; /* set order control variable */
93 int stat, compare; /* status code & sort comparison result */
97 SET_ENTRY FAR *set_ptr;
101 DB_ENTER(DB_ID TASK_ID LOCK_SET(SET_IO));
103 if (nset_check(set, &set, (SET_ENTRY FAR * FAR *)&set_ptr) != S_OKAY)
106 /* make sure we have a current record */
107 if ( curr_rec == NULL_DBA )
108 RETURN( dberr(S_NOCR) );
110 /* make sure we have a current owner */
111 if ( *(co_ptr = &curr_own[set]) == NULL_DBA )
112 RETURN( dberr(S_NOCO) );
114 crec = orec = mrec = nrec = NULL;
116 /* read current record */
117 if ( dio_read( curr_rec, (char FAR * FAR *)&crec, PGHOLD ) != S_OKAY )
120 /* read owner record */
121 if ( (stat = dio_read(*co_ptr, (char FAR * FAR *)&orec, PGHOLD)) != S_OKAY ) {
122 dio_release( curr_rec );
125 /* get copy of current record's member ptr for set */
126 if ( (stat = r_gmem(set, crec, (char FAR *)&crmp)) != S_OKAY )
129 /* ensure record not already connected to set */
130 if ( ! crmp.owner == NULL_DBA ) {
131 stat = dberr(S_ISOWNED);
134 /* get set pointer from owner */
135 if ( r_gset(set, orec, (char FAR *)&cosp) != S_OKAY ) {
136 stat = db_status == S_INVOWN ? dberr(S_SYSERR) : db_status;
139 /* set current record's owner to current owner of set */
140 crmp.owner = *co_ptr;
142 cm_ptr = &curr_mem[set];
143 /* make insertion based on set order specfication */
144 if (cosp.first == NULL_DBA) {
146 /* set current owner's first and last to current record */
147 cosp.first = cosp.last = curr_rec;
149 /* set current record's next and previous to null */
150 crmp.next = crmp.prev = NULL_DBA;
153 /* order is as specified in DDL */
154 ordering = set_ptr->st_order;
156 while (TRUE) switch (ordering) {
159 /* perform a linked insertion sort on set -
160 position the current member to the proper place and then
161 switch to order NEXT */
162 for (mdba = cosp.first; TRUE; mdba = cmmp.next) {
163 /* read member record and get member pointer from member
165 if (((stat = dio_read(mdba, (char FAR * FAR *)&mrec, NOPGHOLD)) != S_OKAY) ||
166 ((stat = r_gmem(set, mrec, (char FAR *)&cmmp)) != S_OKAY))
169 /* compare sort fields of current record with member record */
170 compare = sortcmp(set_ptr, crec, mrec);
171 if ((ordering == ASCENDING) ? (compare < 0) : (compare > 0)) {
172 /* found insertion position -
173 make previous member the current member of set and
174 switch to next order processing */
179 if ( cmmp.next == NULL_DBA ) {
180 /* connect at end of list */
188 crmp.next = cosp.first;
189 /* read current owner's first member and get first member's
193 if (((stat = dio_read(mdba, (char FAR * FAR *)&mrec, PGHOLD)) != S_OKAY) ||
194 ((stat = r_gmem(set, mrec, (char FAR *)&cmmp)) != S_OKAY))
197 /* set current member's previous, and current owner's first, to
199 cmmp.prev = cosp.first = curr_rec;
203 /* if no current member, next is same as first */
207 /* insert record after current member */
210 /* read current member record and get member pointer from
213 if (((stat = dio_read(mdba, (char FAR * FAR *)&mrec, PGHOLD)) != S_OKAY) ||
214 ((stat = r_gmem(set, mrec, (char FAR *)&cmmp)) != S_OKAY))
217 /* set current record's next to current member's next */
218 crmp.next = cmmp.next;
220 /* set current record's prev to current member */
223 /* set current member's next ro current record */
224 cmmp.next = curr_rec;
226 if (crmp.next == NULL_DBA) {
227 /* current record at end of list -
228 update set pointer's last member */
229 cosp.last = curr_rec;
232 /* read next member record and member pointer from next member */
234 if (((stat = dio_read(ndba, (char FAR * FAR *)&nrec, PGHOLD)) != S_OKAY) ||
235 ((stat = r_gmem(set, nrec, (char FAR *)&nmmp)) != S_OKAY))
238 /* set previous pointer in next member to current record */
239 nmmp.prev = curr_rec;
242 /* set current member to owner's last pointer */
244 /* switch to order next */
248 /* there are no other possible orderings! */
249 RETURN( dberr(S_SYSERR) );
252 /* increment total members in set */
255 /* check for timestamp */
256 if ( set_ptr->st_flags & TIMESTAMPED ) {
257 file = NUM2INT((FILE_NO)((*co_ptr >> FILESHIFT) & FILEMASK), ft_offset);
258 cosp.timestamp = dio_pzgetts(file);
262 /* put member pointer back into member record and mark member
265 if (((stat = r_pmem(set, mrec, (char FAR *)&cmmp)) != S_OKAY) ||
266 ((stat = dio_write(mdba, NULL, PGFREE)) != S_OKAY))
270 /* put member pointer back into next record and mark next record
273 if (((stat = r_pmem(set, nrec, (char FAR *)&nmmp)) != S_OKAY) ||
274 ((stat = dio_write(ndba, NULL, PGFREE)) != S_OKAY))
277 /* put set pointer back into owner record and mark owner record as
278 modified; put member pointer back into current record mark current
279 record as modified */
280 if (((stat = r_pset(set, orec, (char FAR *)&cosp)) != S_OKAY) ||
281 ((stat = dio_write(*co_ptr, NULL, PGFREE)) != S_OKAY) ||
282 ((stat = r_pmem(set, crec, (char FAR *)&crmp)) != S_OKAY) ||
283 ((stat = dio_write(curr_rec, NULL, PGFREE)) != S_OKAY))
286 /* set current member to current record */
289 /* check and fetch timestamps */
291 d_utscr(&cm_time[set] TASK_PARM);
293 cs_time[set] = cosp.timestamp;
299 if ( crec ) dio_release( curr_rec );
300 if ( orec ) dio_release( *co_ptr );
301 if ( mrec ) dio_release( mdba );
302 if ( nrec ) dio_release( ndba );
303 RETURN( db_status = stat );
307 /* Compare two sort fields
309 static int sortcmp(set_ptr, mem1, mem2)
310 SET_ENTRY FAR *set_ptr; /* set table entry */
311 char FAR *mem1; /* member record 1 */
312 char FAR *mem2; /* member record 2 */
314 INT rn1, rn2; /* record numbers for mem1 & mem2 */
315 MEMBER_ENTRY FAR *mt1, FAR *mt2;
316 MEMBER_ENTRY FAR *mt;
318 int cmp; /* fldcmp result */
320 SORT_ENTRY FAR *srt1_ptr, FAR *srt2_ptr;
321 FIELD_ENTRY FAR *fld_ptr;
323 /* extract record numbers from record header */
324 bytecpy(&rn1, mem1, sizeof(INT));
325 rn1 &= ~RLBMASK; /* mask off rlb */
326 bytecpy(&rn2, mem2, sizeof(INT));
327 rn2 &= ~RLBMASK; /* mask off rlb */
329 rn1 += curr_db_table->rt_offset;
330 rn2 += curr_db_table->rt_offset;
333 /* locate member_table entries for these record types */
335 for (mem = set_ptr->st_members, memtot = mem + set_ptr->st_memtot,
336 mt = &member_table[mem];
339 if ( mt->mt_record == rn1 ) {
344 if ( mt->mt_record == rn2 ) {
350 /* set maxflds to number of sort fields in set (min(mt1,mt2)) */
351 maxflds = (mt1->mt_totsf <= mt2->mt_totsf) ? mt1->mt_totsf : mt2->mt_totsf;
353 /* do comparison for each field */
354 for (srt1_ptr = &sort_table[mt1->mt_sort_fld],
355 srt2_ptr = &sort_table[mt2->mt_sort_fld];
357 ++srt1_ptr, ++srt2_ptr) {
358 /* compare the two fields */
359 /* computation is pointer to next sort field in member record */
360 fld_ptr = &field_table[srt1_ptr->se_fld];
361 if ((cmp = fldcmp(fld_ptr, mem1 + fld_ptr->fd_ptr,
362 mem2 + field_table[srt2_ptr->se_fld].fd_ptr)))
363 return (cmp); /* return at first unequal fields */
368 /* vpp -nOS2 -dUNIX -nBSD -nVANILLA_BSD -nVMS -nMEMLOCK -nWINDOWS -nFAR_ALLOC -f/usr/users/master/config/nonwin connect.c */