1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 *
22 * Copyright 1997 Sun Microsystems, Inc.  All Rights Reserved.
23 * Use is subject to license terms.
24 */
25
26#pragma ident	"%Z%%M%	%I%	%E% SMI"
27
28#include "sh_table.h"
29#include "subtree.h"
30
31Table *first_table=NULL;
32Table *last_table=NULL;
33
34static Subid dst_subids[1024];
35static int dst_len;
36
37void trace_tables()
38{
39        Table *tp;
40
41
42        trace("TABLES:\n");
43        for(tp = first_table; tp; tp = tp->next_table)
44        {
45                trace("\t%-30s %-30s",
46                        tp->agent->name?tp->agent->name:"UNKNOWN",
47                        SSAOidString(&(tp->name)));
48
49                trace(" %[%d-%d] [%d-%d] view:%s status:%d\n",
50                        tp->first_column_subid,
51                        tp->last_column_subid,
52/*
53                        SSAOidString(&(tp->indexs)),
54*/
55                        tp->first_index_subid,
56                        tp->last_index_subid,
57			SSAStringToChar(tp->regTblView),
58			tp->regTblStatus);
59/*
60        String  regTblView;
61        Integer regTblStatus;
62*/
63        }
64        trace("\n");
65}
66
67
68/****************************************************************/
69
70int is_first_entry(Table *table)
71{
72	Table *tp;
73
74
75	for(tp = first_table; tp; tp = tp->next_table)
76	{
77		if(table == tp)
78		{
79			continue;
80		}
81
82		if(SSAOidCmp(&(tp->name), &(table->name)) == 0)
83		{
84/*
85			if(SSAOidCmp(&(tp->indexs), &(table->indexs)) < 0)
86			{
87				return False;
88			}
89*/
90			if(tp->first_index_subid < table->first_index_subid)
91			{
92				return False;
93			}
94		}
95	}
96
97	return True;
98}
99
100
101/****************************************************************/
102
103void table_list_delete()
104{
105	Table *next;
106
107	while(first_table)
108	{
109		next = first_table->next_table;
110		table_free(first_table);
111		first_table = next;
112	}
113
114	first_table = NULL;
115	last_table = NULL;
116}
117
118
119/****************************************************************/
120
121void table_free(Table *tp)
122{
123	if(tp == NULL)
124	{
125		return;
126	}
127
128	if(tp->name.subids)
129	{
130		free(tp->name.subids);
131	}
132	/* free the TblViewString */
133	if(tp->regTblView.chars != NULL &&
134	   tp->regTblView.len != 0)
135		free(tp->regTblView.chars);
136
137/*
138	if(tp->indexs.subids)
139	{
140		free(tp->indexs.subids);
141	}
142*/
143
144	free(tp);
145}
146
147void delete_all_tables_for_agent(Agent *agent)
148{
149        Table *tp = first_table;
150        Table *next, *last = NULL;
151
152        while(tp)
153        {
154                next = tp->next_table;
155                if(tp->agent == agent){
156                  if(last == NULL)
157                        first_table = next;
158                  else
159                        last->next_table = next;
160                  table_free(tp);
161                }else{
162                        last = tp;
163                }
164                tp = next;
165        }
166        last_table = last;
167
168}
169
170void table_detach(Table *tgt)
171{
172  Table *sp, *last=NULL;
173
174        if(tgt == NULL) return;
175        for(sp = first_table; sp; sp = sp->next_table)
176        {
177                if(sp == tgt)
178                {
179                        break;
180                }
181
182                last = sp;
183        }
184
185	if(sp==NULL) return;
186        if(last == NULL)
187        {
188                first_table = tgt->next_table;
189                tgt->next_table = NULL;
190        }
191        else
192        {
193                last->next_table = tgt->next_table;
194                tgt->next_table = NULL;
195        }
196}
197
198static int subids_cat(Subid *subids, int len)
199{
200
201	if(subids == NULL) return -1;
202        memcpy(&(dst_subids[dst_len]), subids, len * sizeof(Subid));
203	dst_len += len;
204	return 0;
205}
206
207
208static int activate_table_oids(Table *tp, int type)
209{
210  Subid index;
211  Subid one = 1;
212  Subid column;
213  Subtree *sp;
214  TblTag *tbl_tag=NULL;
215
216
217
218 for(index = tp->first_index_subid; index <= tp->last_index_subid; index++){
219  for(column = tp->first_column_subid; column <= tp->last_column_subid; column++)
220  {
221    dst_subids[0]='\0';
222    dst_len = 0;
223    if(subids_cat(tp->name.subids, tp->name.len) == -1)
224    {
225            return -1;
226    }
227    if(subids_cat(&one, 1) == -1)
228    {
229            return -1;
230    }
231    if(subids_cat(&column, 1) == -1)
232    {
233            return -1;
234    }
235    if(subids_cat(&index, 1) == -1)
236    {
237            return -1;
238    }
239    /* search , compare and/or replace(purge and add) */
240    sp=subtree_find(dst_subids,dst_len);
241    if(sp!=NULL) sp->regTreeStatus = type;
242  }
243 }
244  return 0;
245}
246
247static int activate_table_col_obj(Table *tp)
248{
249  Subid one = 1;
250  Subid column;
251  Subid index;
252  Subtree *sp;
253  TblTag *tbl_tag=NULL;
254
255
256  for(column = tp->first_column_subid; column <= tp->last_column_subid; column++)
257  {
258    dst_subids[0]='\0';
259    dst_len = 0;
260    if(subids_cat(tp->name.subids, tp->name.len) == -1)
261    {
262            return -1;
263    }
264     dst_subids[dst_len-1]++;
265/*
266    if(subids_cat(&one, 1) == -1)
267    {
268            return -1;
269    }
270*/
271    if(subids_cat(&column, 1) == -1)
272    {
273            return -1;
274    }
275    /* search , compare and/or replace(purge and add) */
276    sp=subtree_find(dst_subids,dst_len);
277
278    if(sp != NULL && sp->tbl_tag != NULL)
279    {
280       if(sp->tbl_tag->entry_index > tp->first_index_subid)
281            subtree_purge(dst_subids,dst_len);
282       else
283		continue;
284    }
285    tbl_tag = (TblTag*)calloc(1,sizeof(TblTag));
286    if(tbl_tag != NULL){
287      tbl_tag->entry_index = tp->first_index_subid;
288      tbl_tag->type = TBL_TAG_TYPE_COL;
289      tbl_tag->table = tp;
290    }
291    if(subtree_add(tp->agent, dst_subids, dst_len,tbl_tag) == -1)
292    {
293      sprintf(error_label, "subtree_add() failed for table %s for the agent %s",           SSAOidString(&(tp->name)),
294      tp->agent&&tp->agent->name?tp->agent->name:"UNKNOWN");
295      dst_subids[0]='\0';
296      dst_len = 0;
297      if(tbl_tag) free(tbl_tag);
298      tbl_tag = NULL;
299      return -1;
300    }
301  }
302  return 0;
303}
304
305int activate_table(Table *tp)
306{
307 if( activate_table_oids(tp,SSA_OPER_STATUS_ACTIVE)!=0 ||
308     activate_table_col_obj(tp)!=0 )
309	return -1;
310 return 0;
311}
312
313int deactivate_table(Table *tp)
314{
315 if( activate_table_oids(tp,SSA_OPER_STATUS_NOT_IN_SERVICE)!=0 ||
316      delete_table_col_obj(tp)!=0 ) return -1;
317 return 0;
318}
319
320/* whether oid1 is substring of oid2 */
321static int is_suboid(Oid* oid1,Oid *oid2)
322{
323        int min;
324        int i;
325
326
327        if(oid1 == NULL)
328        {
329                fprintf(stderr, "BUG: SSAOidCmp(): oid1 is NULL");
330                return -2;
331        }
332
333        if(oid2 == NULL)
334        {
335                fprintf(stderr, "BUG: SSAOidCmp(): oid2 is NULL");
336                return -2;
337        }
338
339        min = MIN(oid1->len, oid2->len);
340
341        for(i = 0; i < min; i++)
342        {
343                if(oid1->subids[i] > oid2->subids[i])
344                {
345                        return -1;
346                }
347
348                if(oid1->subids[i] < oid2->subids[i])
349                {
350                        return -1;
351                }
352        }
353	if(oid1->len <= oid2->len) return 0;
354	return -1;
355}
356
357static Subtree* get_oid_in_col_container(Subtree* cur_subtree, int *elem_exist)
358{
359        Subtree *sp;
360        int ret;
361
362	*elem_exist = FALSE;
363        for(sp = cur_subtree; sp; sp = sp->next_subtree)
364        {
365		if(sp==cur_subtree) continue;
366		ret = is_suboid(&(cur_subtree->name),&(sp->name));
367                if(ret == 0)
368                {
369			*elem_exist = TRUE;
370			if(subtree_is_valid(sp)) return sp;
371			continue;
372                }
373        }
374
375        return NULL;
376
377}
378
379int delete_table_oid(Table *tp)
380{
381  Subid index;
382  Subid one = 1;
383  Subid column;
384  Subtree *sp;
385  TblTag *tbl_tag=NULL;
386
387
388
389 for(index = tp->first_index_subid; index <= tp->last_index_subid; index++){
390  for(column = tp->first_column_subid; column <= tp->last_column_subid; column++)
391  {
392    dst_subids[0]='\0';
393    dst_len = 0;
394    if(subids_cat(tp->name.subids, tp->name.len) == -1)
395    {
396            return -1;
397    }
398    if(subids_cat(&one, 1) == -1)
399    {
400            return -1;
401    }
402    if(subids_cat(&column, 1) == -1)
403    {
404            return -1;
405    }
406    if(subids_cat(&index, 1) == -1)
407    {
408            return -1;
409    }
410    if(subtree_purge(dst_subids,dst_len) == FALSE)
411	return -1;
412  }
413 }
414  return 0;
415}
416
417int delete_table_col_obj(Table *tp)
418{
419  /* 1. delete the oids from the subtree list.
420     2. scan thru the columarn object, if matching the table, delete and
421	find a new one for it.
422   */
423  Subid one = 1;
424  Subid column;
425  Subid index;
426  Subtree *sp, *sp1;
427  TblTag *tbl_tag=NULL;
428  int elem_exist;
429
430
431  for(column = tp->first_column_subid; column <= tp->last_column_subid; column++)
432  {
433    dst_subids[0]='\0';
434    dst_len = 0;
435    if(subids_cat(tp->name.subids, tp->name.len) == -1)
436    {
437            return -1;
438    }
439    if(subids_cat(&one, 1) == -1)
440    {
441            return -1;
442    }
443    if(subids_cat(&column, 1) == -1)
444    {
445            return -1;
446    }
447    /* search , compare and/or replace(purge and add) */
448    if((sp=subtree_find(dst_subids,dst_len)) != NULL)
449    {
450       if(sp->tbl_tag != NULL &&
451          sp->tbl_tag->entry_index == tp->first_index_subid &&
452	  sp->tbl_tag->table != NULL && sp->tbl_tag->table == tp)
453       {
454	    sp1 = get_oid_in_col_container(sp,&elem_exist);
455
456            subtree_purge(dst_subids,dst_len);
457
458	    /* find the right table or oid */
459	    if( sp1 != NULL &&
460		sp1->tbl_tag != NULL && sp1->tbl_tag->table != NULL &&
461		sp1->agent != NULL )
462	    {
463              tbl_tag = (TblTag*)calloc(1,sizeof(TblTag));
464              if(tbl_tag != NULL){
465                tbl_tag->type = TBL_TAG_TYPE_COL;
466                tbl_tag->entry_index = sp1->tbl_tag->table->first_index_subid;
467	        tbl_tag->table = sp1->tbl_tag->table;
468              }
469    	      if(subtree_add(sp1->agent, dst_subids, dst_len,tbl_tag) == -1)
470    	      {
471            	sprintf(error_label, "subtree_add() failed for table %s for the agent %s",
472                    SSAOidString(&(sp1->tbl_tag->table->name)),
473                    sp1->agent&&sp1->agent->name?sp1->agent->name:"UNKNOWN");
474		    dst_subids[0]='\0';
475		    dst_len = 0;
476            	    if(tbl_tag) free(tbl_tag);
477            	    tbl_tag = NULL;
478            	    return -1;
479    	      }
480	   }
481       }
482    }
483  }
484  return 0;
485}
486
487int delete_table(Table *tp)
488{
489  if(tp==NULL) return -1;
490  /* (mibpatch) don't call the following two lines, when
491     the table is mirror, delete the subtree */
492  if(tp->mirror_flag==1){
493	/* delete the subtree */
494     subtree_purge(tp->name.subids,tp->name.len);
495  }else{
496  	if( delete_table_oid(tp)!= 0 ||
497      	delete_table_col_obj(tp)!=0 ) return -1;
498  }
499  /*destroy the table */
500  table_detach(tp);
501  table_free(tp);
502  return 0;
503}
504
505int activate_table_for_agent(Agent* agent)
506{
507  Table *sp;
508
509  for(sp = first_table; sp; sp = sp->next_table)
510  {
511	if(sp->agent != NULL && sp->agent == agent){
512	  activate_table(sp);
513	  sp->regTblStatus = SSA_OPER_STATUS_ACTIVE;
514	}
515  }
516  return 0;
517}
518
519int deactivate_table_for_agent(Agent* agent)
520{
521  Table *sp;
522
523  for(sp = first_table; sp; sp = sp->next_table)
524  {
525	if(sp->agent != NULL && sp->agent == agent){
526	  deactivate_table(sp);
527	  sp->regTblStatus = SSA_OPER_STATUS_NOT_IN_SERVICE;
528	}
529  }
530  return 0;
531}
532
533void delete_all_table_from_agent(Agent *agent)
534{
535  Table *sp=first_table;
536  Table *next, *last=NULL;
537
538  while(sp)
539  {
540        next = sp->next_table;
541
542        if(sp->agent != NULL && sp->agent == agent){
543                if(last==NULL){
544                        first_table = next;
545                }else{
546                        last->next_table=next;
547                }
548                if( delete_table_oid(sp)!= 0 ||
549                    delete_table_col_obj(sp)!=0 ){
550                        error("table deletion error");
551                        return ;
552                }
553                table_free(sp);
554        }else{
555                last = sp;
556        }
557        sp = next;
558  }
559}
560
561void create_mirror_table_from_subtree(Subtree* subtree)
562{
563  Table *table, *tmp_table, *last_table;
564
565  if(subtree==NULL) return;
566  if((table=(Table*)calloc(1,sizeof(Table)))==NULL) return;
567  table->regTblStatus = subtree->regTreeStatus;
568  table->mirror_flag = 1;
569  if(subtree->agent!=NULL){
570  	table->regTblIndex = ++subtree->agent->agentTblIndex;
571  	table->regTblAgentID = subtree->agent->agentID;
572  }
573  SSAOidCpy(&(table->name),&(subtree->name),error_label);
574  table->agent = subtree->agent;
575  subtree->mirror_tag = (struct _MirrorTag *)calloc(1,sizeof(struct _MirrorTag));
576  if(subtree->mirror_tag!=NULL) subtree->mirror_tag->table = table;
577
578  /* insert the table */
579  /* later sort it in order */
580
581  if(first_table==NULL){
582	first_table = table;
583  }else{
584	last_table = NULL;
585	for(tmp_table=first_table;tmp_table;tmp_table=tmp_table->next_table){
586		if(tmp_table->regTblAgentID > table->regTblAgentID ||
587		   (tmp_table->regTblAgentID==table->regTblAgentID &&
588		    tmp_table->regTblIndex > table->regTblIndex))
589			break;
590		last_table = tmp_table;
591	}
592	if(last_table==NULL){
593		table->next_table = first_table;
594		first_table = table;
595	}else{
596		table->next_table = last_table->next_table;
597		last_table->next_table = table;
598	}
599  }
600}
601