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 librararies 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: recfcns.c /main/2 1996/05/09 04:13:59 drk $ */
25 * COMPONENT_NAME: austext
42 * OBJECT CODE ONLY SOURCE MATERIALS
44 /*---------------------------------------------------------------------------
45 recfcns.c - db_VISTA Record Access/Manipulation Functions
47 Copyright (C) 1984, 1985, 1986 by Raima Corporation.
48 ---------------------------------------------------------------------------*/
50 /* ********************** EDIT HISTORY *******************************
52 SCR DATE INI DESCRIPTION
53 ----- --------- --- -----------------------------------------------------
54 158 15-JUN-88 RSC passed new flag to key_bldcom.
55 103 27-Jun-88 RSC Improve generation of single user version
56 04-Aug-88 RTK MULTI_TASK changes
57 310 10-Aug-88 RSC Cleanup function prototype.
58 420 16-Aug-88 RTK Missing FAR pointer
68 /* toggle for checking struct key modifications */
69 static int struct_key_chk = 1;
71 /* Check a field for permission to change it
73 r_chkfld(field, fld_ptr, rec, data )
74 INT field; /* field_table entry number */
75 FIELD_ENTRY FAR *fld_ptr; /* corresponds to field */
76 char FAR *rec; /* pointer to record slot */
77 CONST char FAR *data; /* pointer to data area containing field contents */
82 char FAR *fptr, ckey[256];
84 FIELD_ENTRY FAR *sfld_ptr;
85 RECORD_ENTRY FAR *rec_ptr;
87 bytecpy(&rn, rec, sizeof(INT));
88 rn &= ~RLBMASK; /* mask off rlb */
89 if ( rn != NUM2EXT(fld_ptr->fd_rec, rt_offset) )
90 return( dberr(S_INVFLD) );
92 rec_ptr = &record_table[fld_ptr->fd_rec];
93 fld = FLDMARK*rn + field - rec_ptr->rt_fields;
95 if ( fld_ptr->fd_type == COMKEY ) {
97 /* build compound key value. NOTE: cflag MUST be the same here as for
98 the call to key_bldcom in recwrite, which calls this function. */
99 fptr = rec + rec_ptr->rt_data;
100 key_bldcom(field, fptr, ckey, FALSE);
104 fptr = rec + fld_ptr->fd_ptr;
106 /* do nothing unless the new value is different */
107 if (fldcmp(fld_ptr, data, fptr) == 0)
108 return( db_status = S_OKAY );
110 /* if this is a unique key field, make sure the key does not already
113 if ( fld_ptr->fd_key == UNIQUE ) {
115 /* If the key field is not optional, or optional and stored */
116 if ((!(fld_ptr->fd_flags & OPTKEYMASK) || r_tstopt(fld_ptr, rec)) &&
117 (d_keyfind(fld, data CURRTASK_PARM CURR_DB_PARM) == S_OKAY)) {
118 /* another record is already using this key value */
119 db_status = S_DUPLICATE;
122 if ( db_status == S_DUPLICATE ) return( db_status );
124 /* if field is grouped, call r_chkfld for 1st entry of each sub-field */
125 if ( fld_ptr->fd_type == GROUPED ) {
126 for (i = field + 1, sfld_ptr = fld_ptr + 1;
127 (i < size_fd) && (sfld_ptr->fd_flags & STRUCTFLD);
129 fptr = (char *)data - (sfld_ptr->fd_ptr -
130 record_table[sfld_ptr->fd_rec].rt_data);
131 if (r_chkfld(i, sfld_ptr, rec, fptr) != S_OKAY)
135 return( db_status = S_OKAY );
139 /* Delete the current record
141 r_delrec( rt, db_addr )
145 char FAR *rec; /* ptr to record slot */
146 char FAR *fptr; /* field data ptr */
147 char ckey[256]; /* compound key data */
154 RECORD_ENTRY FAR *rec_ptr;
155 register FIELD_ENTRY FAR *fld_ptr;
157 if ( dio_read( db_addr, (char FAR * FAR *)&rec, PGHOLD) != S_OKAY )
160 rec_ptr = &record_table[rt];
161 /* remove any key fields from the key files */
162 for (fld = rec_ptr->rt_fields, fld_ptr = &field_table[fld];
163 (fld < size_fd) && (fld_ptr->fd_rec == rt);
165 if ( fld_ptr->fd_key != NOKEY ) {
166 if ( fld_ptr->fd_type == COMKEY ) {
167 key_bldcom(fld, rec + rec_ptr->rt_data, ckey, TRUE);
171 fptr = rec + fld_ptr->fd_ptr;
173 /* delete the key if it exists */
174 if ((!(fld_ptr->fd_flags & OPTKEYMASK) || r_tstopt(fld_ptr, rec)) &&
175 (key_delete(fld, fptr, db_addr) != S_OKAY))
179 fno = NUM2INT((FILE_NO)((db_addr >> FILESHIFT) & FILEMASK), ft_offset);
180 rno = ADDRMASK & db_addr;
182 /* update timestamp, if necessary */
183 if ( rec_ptr->rt_flags & TIMESTAMPED ) {
184 timestamp = dio_pzgetts(fno);
185 bytecpy( rec + RECCRTIME, ×tamp, sizeof(ULONG));
186 bytecpy( rec + RECUPTIME, ×tamp, sizeof(ULONG));
189 dio_write(db_addr, NULL, PGFREE);
191 /* place this record onto the delete chain */
198 /* Get data field from record
200 r_gfld(fld_ptr, rec, data )
201 FIELD_ENTRY FAR *fld_ptr;
202 char FAR *rec; /* pointer to record */
203 char FAR *data; /* pointer to data area to contain field contents */
205 register int kt_lc; /* loop control */
207 register FIELD_ENTRY FAR *kfld_ptr;
208 register KEY_ENTRY FAR *key_ptr;
210 bytecpy(&rn, rec, sizeof(INT));
212 return( db_status = S_DELETED );
215 if ( rn & RLBMASK ) {
216 rn &= ~RLBMASK; /* mask off rlb */
217 rlb_status = S_LOCKED;
220 rlb_status = S_UNLOCKED;
224 rn += curr_db_table->rt_offset;
227 if ( fld_ptr->fd_rec != rn )
228 return( dberr(S_INVFLD) );
230 if ( fld_ptr->fd_type == KEY ) {
231 /* clear compound key data area */
232 byteset(data, '\0', fld_ptr->fd_len);
234 /* copy each field of compound key to data area */
235 for (kt_lc = size_kt - fld_ptr->fd_ptr,
236 key_ptr = &key_table[fld_ptr->fd_ptr];
237 (--kt_lc >= 0) && (&field_table[key_ptr->kt_key] == fld_ptr);
239 kfld_ptr = &field_table[key_ptr->kt_field];
240 bytecpy(data + key_ptr->kt_ptr, rec + kfld_ptr->fd_ptr,
245 bytecpy(data, rec + fld_ptr->fd_ptr, fld_ptr->fd_len);
247 return( db_status = S_OKAY );
251 /* Get member pointer from record
253 r_gmem(set, rec, mem_addr )
254 int set; /* set table entry number */
255 char FAR *rec; /* pointer to record */
256 char FAR *mem_addr; /* pointer to member pointer */
259 register int mem, memtot;
260 SET_ENTRY FAR *set_ptr;
261 register MEMBER_ENTRY FAR *mem_ptr;
263 /* search member list of set for record */
264 set_ptr = &set_table[set];
265 bytecpy(&rt, rec, sizeof(INT));
267 for (mem = set_ptr->st_members, memtot = mem + set_ptr->st_memtot,
268 mem_ptr = &member_table[mem];
271 if (NUM2EXT(mem_ptr->mt_record, rt_offset) == rt) {
272 /* have found correct member record */
273 bytecpy(mem_addr, rec + mem_ptr->mt_mem_ptr, MEMPSIZE);
274 return( db_status = S_OKAY );
277 /* this record is not member of set */
278 return( dberr(S_INVMEM) );
282 /* Get set pointer from record
284 r_gset(set, rec, setptr )
285 int set; /* set table entry number */
286 char FAR *rec; /* pointer to record */
287 char FAR *setptr; /* pointer to set pointer */
291 SET_ENTRY FAR *set_ptr;
293 set_ptr = &set_table[set];
294 bytecpy(&rt, rec, sizeof(INT));
295 if (NUM2EXT(set_ptr->st_own_rt, rt_offset) == (rt & ~RLBMASK)) {
297 if ( set_ptr->st_flags & TIMESTAMPED )
301 len = SETPSIZE - sizeof(ULONG);
302 bytecpy(setptr, rec + set_ptr->st_own_ptr, len);
303 return( db_status = S_OKAY );
305 return( dberr(S_INVOWN) );
309 /* Put data field into record
311 r_pfld(field, fld_ptr, rec, data, db_addr )
312 INT field; /* field_table entry number */
313 FIELD_ENTRY FAR *fld_ptr; /* corresponds to field */
314 char FAR *rec; /* pointer to existing record */
315 CONST char FAR *data; /* pointer to data area containing new field contents */
316 DB_ADDR FAR *db_addr;
318 DB_ADDR mdba, odba, dba;
321 register char FAR *fptr;
322 register CONST char FAR *tfptr;
323 register int s, i, strfld;
324 register FIELD_ENTRY FAR *sfld_ptr;
325 register SORT_ENTRY FAR *srt_ptr;
326 DB_ADDR FAR *co_ptr, FAR *cm_ptr;
329 fptr = rec + fld_ptr->fd_ptr;
331 /* do nothing unless the new value is different */
332 if (fldcmp(fld_ptr, fptr, data) == 0)
335 bytecpy(&dba, db_addr, DB_ADDR_SIZE);
337 /* if this is a key field, change the key file also */
338 if ((fld_ptr->fd_key != NOKEY) &&
339 (!(fld_ptr->fd_flags & OPTKEYMASK) || r_tstopt(fld_ptr, rec))) {
340 /* delete the old key and insert the new one */
341 if ( key_delete(field, fptr, dba) == S_OKAY ) {
342 if ( key_insert( field, data, dba ) != S_OKAY )
346 return( db_status == S_NOTFOUND? dberr(S_KEYERR): db_status );
348 /* if subfield of struct field, check to see if struct is a key */
349 if ( struct_key_chk && fld_ptr->fd_flags & STRUCTFLD ) {
350 for (strfld = field - 1, sfld_ptr = &field_table[strfld];
351 sfld_ptr->fd_type != GROUPED;
352 --strfld, --sfld_ptr)
353 ; /* find struct field */
354 if ((sfld_ptr->fd_key != NOKEY) &&
355 /* make sure it is stored */
356 (!(sfld_ptr->fd_flags & OPTKEYMASK) || r_tstopt(sfld_ptr, rec))) {
357 /* delete the old struct key */
358 if (key_delete(strfld, rec + sfld_ptr->fd_ptr, dba) != S_OKAY)
365 /* copy data into record area */
366 switch ( fld_ptr->fd_type ) {
368 if ( fld_ptr->fd_dim[1] )
369 bytecpy(fptr, data, fld_ptr->fd_len);
370 else if ( fld_ptr->fd_dim[0] )
371 strncpy(fptr, data, fld_ptr->fd_len);
376 if ( ! fld_ptr->fd_dim[0] ) {
377 /* non-arrayed structure */
379 for (i = field + 1, sfld_ptr = fld_ptr + 1;
380 (i < size_fd) && (sfld_ptr->fd_flags & STRUCTFLD);
382 tfptr = data + sfld_ptr->fd_ptr - fld_ptr->fd_ptr;
383 if ( r_pfld(i, sfld_ptr, rec, tfptr, &dba) != S_OKAY )
387 if ( db_status != S_OKAY ) return( db_status );
390 /* arrayed struct fall-thru to a full field copy */
392 bytecpy(fptr, data, fld_ptr->fd_len);
394 /* if this field is part of an ordered set, reconnect */
395 if (fld_ptr->fd_flags & SORTFLD) {
396 for (s = 0, srt_ptr = sort_table; s < size_srt; ++s, ++srt_ptr) {
397 if ( srt_ptr->se_fld == field ) {
398 sn = srt_ptr->se_set;
399 if ( r_gmem( sn, rec, memp ) != S_OKAY ) return( db_status );
400 if ( ! null_dba(memp+MP_OWNER) ) {
402 odba = *(co_ptr = &curr_own[sn]);
403 mdba = *(cm_ptr = &curr_mem[sn]);
405 /* set current owner and member to sorted set */
406 bytecpy(co_ptr, memp+MP_OWNER, DB_ADDR_SIZE);
409 /* calculate set constant */
410 set = NUM2EXT(sn + SETMARK, st_offset);
412 /* disconnect from prior order set and reconnect in new order */
413 d_discon(set CURRTASK_PARM CURR_DB_PARM);
414 d_connect(set CURRTASK_PARM CURR_DB_PARM);
424 /* insert the new struct key */
425 if ( key_insert( strfld, rec + sfld_ptr->fd_ptr, dba ) != S_OKAY )
432 /* Put member pointer into record
434 r_pmem(set, rec, mem_addr )
435 int set; /* set table entry number */
436 char FAR *rec; /* pointer to record */
437 char FAR *mem_addr; /* pointer to member pointer */
440 register int mem, memtot;
441 SET_ENTRY FAR *set_ptr;
442 register MEMBER_ENTRY FAR *mem_ptr;
444 /* search member list of set for record */
445 set_ptr = &set_table[set];
446 bytecpy(&rt, rec, sizeof(INT));
448 for (mem = set_ptr->st_members, memtot = mem + set_ptr->st_memtot,
449 mem_ptr = &member_table[mem];
452 if (NUM2EXT(mem_ptr->mt_record, rt_offset) == rt) {
453 /* have found correct member record */
454 bytecpy(rec + mem_ptr->mt_mem_ptr, mem_addr, MEMPSIZE);
455 return( db_status = S_OKAY );
458 /* this record is not member of set */
459 return( dberr(S_INVMEM) );
463 /* Put set pointer into record
465 r_pset(set, rec, setptr )
466 int set; /* set table entry number */
467 char FAR *rec; /* pointer to record */
468 char FAR *setptr; /* pointer to set pointer */
472 SET_ENTRY FAR *set_ptr;
474 set_ptr = &set_table[set];
475 bytecpy(&rt, rec, sizeof(INT));
476 if (NUM2EXT(set_ptr->st_own_rt, rt_offset) == (rt & ~RLBMASK)) {
478 if ( set_ptr->st_flags & TIMESTAMPED )
482 len = SETPSIZE - sizeof(ULONG);
483 bytecpy(rec + set_ptr->st_own_ptr, setptr, len);
484 return( db_status = S_OKAY );
487 return( dberr(S_INVOWN) );
492 /* Set the current set member from record
494 r_smem( db_addr, set )
495 DB_ADDR FAR *db_addr;
501 char mem[MEMPSIZE], FAR *ptr;
504 bytecpy(&dba, db_addr, DB_ADDR_SIZE);
506 /* make sure record is owned */
507 if ((dio_read(dba, (char FAR * FAR *)&ptr, NOPGHOLD) != S_OKAY) ||
508 (r_gmem(set, ptr, mem) != S_OKAY))
511 if ( null_dba( mem+MP_OWNER ) ) return( dberr( S_NOTCON ) );
513 bytecpy( &curr_own[set], mem+MP_OWNER, DB_ADDR_SIZE );
515 /* ownership okay, set the member */
518 nset = NUM2EXT(set + SETMARK, st_offset);
521 d_utsco( nset, &co_time[set] CURRTASK_PARM CURR_DB_PARM );
522 d_utscm( nset, &cm_time[set] CURRTASK_PARM CURR_DB_PARM );
525 d_utscs( nset, &cs_time[set] CURRTASK_PARM CURR_DB_PARM );
527 return( db_status = S_OKAY );
530 /* Set the optional key field "stored" bit */
531 r_setopt( fld_ptr, rec )
532 FIELD_ENTRY FAR *fld_ptr; /* field table entry of optional key */
533 char FAR *rec; /* Pointer to record */
535 int offset; /* offset to the bit map */
536 int keyndx; /* index into bit map of this key */
537 int byteno, bitno; /* position within bit map of this key */
539 /* calculate the position to the bit map */
540 offset = (record_table[fld_ptr->fd_rec].rt_flags & TIMESTAMPED) ?
541 (RECHDRSIZE + 2*sizeof(LONG)) : RECHDRSIZE;
543 /* extract the index into the bit map of this key */
544 keyndx = (((fld_ptr->fd_flags & OPTKEYMASK) >> OPTKEYSHIFT) & OPTKEYNDX) - 1;
545 if ( keyndx < 0 ) return( dberr(S_SYSERR) );
547 /* determine which byte, and which bit within the byte */
548 byteno = keyndx/BITS_PER_BYTE;
549 bitno = keyndx - byteno*BITS_PER_BYTE;
552 rec[byteno + offset] |= 1 << (BITS_PER_BYTE - bitno - 1);
554 return( db_status = S_OKAY );
557 /* Clear the optional key field "stored" bit */
558 r_clropt( fld_ptr, rec )
559 FIELD_ENTRY FAR *fld_ptr; /* Field table entry of optional key */
560 char FAR *rec; /* Pointer to record */
562 int offset; /* offset to the bit map */
563 int keyndx; /* index into bit map of this key */
564 int byteno, bitno; /* position within bit map of this key */
566 /* calculate the position to the bit map */
567 offset = (record_table[fld_ptr->fd_rec].rt_flags & TIMESTAMPED) ?
568 (RECHDRSIZE + 2*sizeof(LONG)) : RECHDRSIZE;
570 /* extract the index into the bit map of this key */
571 keyndx = (((fld_ptr->fd_flags & OPTKEYMASK) >> OPTKEYSHIFT) & OPTKEYNDX) - 1;
572 if ( keyndx < 0 ) return( dberr(S_SYSERR) );
574 /* determine which byte, and which bit within the byte */
575 byteno = keyndx / BITS_PER_BYTE;
576 bitno = keyndx - byteno*BITS_PER_BYTE;
579 rec[byteno + offset] &= ~(1 << (BITS_PER_BYTE - bitno - 1));
584 /* Test the optional key field "stored" bit */
585 r_tstopt( fld_ptr, rec )
586 FIELD_ENTRY FAR *fld_ptr; /* Field table entry of optional key */
587 char FAR *rec; /* Pointer to record */
589 int offset; /* offset to the bit map */
590 int keyndx; /* index into bit map of this key */
591 int byteno, bitno; /* position within bit map of this key */
593 /* calculate the position to the bit map */
594 offset = (record_table[fld_ptr->fd_rec].rt_flags & TIMESTAMPED) ?
595 (RECHDRSIZE + 2*sizeof(LONG)) : RECHDRSIZE;
597 /* extract the index into the bit map of this key */
598 keyndx = (((fld_ptr->fd_flags & OPTKEYMASK) >> OPTKEYSHIFT) & OPTKEYNDX) - 1;
599 if ( keyndx < 0 ) return( dberr(S_SYSERR) );
601 /* determine which byte, and which bit within the byte */
602 byteno = keyndx / BITS_PER_BYTE;
603 bitno = keyndx - byteno*BITS_PER_BYTE;
605 /* extract the bit */
606 if (rec[byteno + offset] & (1 << (BITS_PER_BYTE - bitno - 1)))
607 return( db_status = S_DUPLICATE );
608 return( db_status = S_OKAY );
610 /* vpp -nOS2 -dUNIX -nBSD -nVANILLA_BSD -nVMS -nMEMLOCK -nWINDOWS -nFAR_ALLOC -f/usr/users/master/config/nonwin recfcns.c */