00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00028 #include <errno.h>
00029
00030 #include "dbprim.h"
00031 #include "dbprim_int.h"
00032
00033 RCSTAG("@(#)$Id: st_add.c,v 1.5 2006/07/13 20:27:36 klmitch Exp $");
00034
00035 unsigned long
00036 st_add(smat_table_t *table, smat_entry_t **entry_p,
00037 smat_head_t *head1, link_loc_t loc1, smat_entry_t *ent1,
00038 smat_head_t *head2, link_loc_t loc2, smat_entry_t *ent2)
00039 {
00040 smat_entry_t *se;
00041 unsigned long retval = 0;
00042 unsigned int freeflags = 0;
00043 db_key_t key;
00044
00045 initialize_dbpr_error_table();
00046
00047
00048
00049
00050 if (!st_verify(table) || !sh_verify(head1) || !sh_verify(head2) ||
00051 head1->sh_elem != SMAT_LOC_FIRST || head2->sh_elem != SMAT_LOC_SECOND ||
00052 (ent1 && !se_verify(ent1)) || (ent2 && !se_verify(ent2)) ||
00053 ((loc1 == LINK_LOC_BEFORE || loc1 == LINK_LOC_AFTER) && !ent1) ||
00054 ((loc2 == LINK_LOC_BEFORE || loc2 == LINK_LOC_AFTER) && !ent2))
00055 return DB_ERR_BADARGS;
00056
00057
00058 if ((head1->sh_table && head1->sh_table != table) ||
00059 (head2->sh_table && head2->sh_table != table) ||
00060 (ent1 && ent1->se_table != table) ||
00061 (ent2 && ent2->se_table != table))
00062 return DB_ERR_WRONGTABLE;
00063
00064 if (!(se = _smat_alloc()))
00065 return ENOMEM;
00066
00067 freeflags |= ST_REM_FREE;
00068
00069 se->se_object[SMAT_LOC_FIRST] = sh_object(head1);
00070 se->se_object[SMAT_LOC_SECOND] = sh_object(head2);
00071 dk_key(&key) = se->se_object;
00072 dk_len(&key) = sizeof(se->se_object);
00073
00074
00075 if ((retval = ht_add(&table->st_table, &se->se_hash, &key)))
00076 goto error;
00077
00078 freeflags |= ST_REM_HASH;
00079
00080
00081 if ((retval = ll_add(&head1->sh_head, &se->se_link[SMAT_LOC_FIRST], loc1,
00082 ent1 ? &ent1->se_link[SMAT_LOC_FIRST] : 0)))
00083 goto error;
00084
00085 freeflags |= ST_REM_FIRST;
00086
00087
00088 if ((retval = ll_add(&head2->sh_head, &se->se_link[SMAT_LOC_SECOND], loc2,
00089 ent2 ? &ent2->se_link[SMAT_LOC_SECOND] : 0)))
00090 goto error;
00091
00092 head1->sh_table = head2->sh_table = table;
00093 se->se_table = table;
00094
00095 if (entry_p)
00096 *entry_p = se;
00097
00098 return 0;
00099
00100 error:
00101
00102 if ((freeflags & ST_REM_FIRST) &&
00103 ll_remove(&head1->sh_head, &se->se_link[SMAT_LOC_FIRST]))
00104 return DB_ERR_UNRECOVERABLE;
00105
00106
00107 if ((freeflags & ST_REM_HASH) && ht_remove(&table->st_table, &se->se_hash))
00108 return DB_ERR_UNRECOVERABLE;
00109
00110
00111 if (freeflags & ST_REM_FREE)
00112 _smat_free(se);
00113
00114 return retval;
00115 }