gen_lists.c

Go to the documentation of this file.
00001 /************************************* */
00002 /* Rule Set Based Access Control       */
00003 /* Author and (c) 1999-2005:           */
00004 /*   Amon Ott <ao@rsbac.org>           */
00005 /* Generic lists for all parts         */
00006 /* Last modified: 01/Apr/2005          */
00007 /************************************* */
00008 
00009 #include <linux/sched.h>
00010 #include <linux/smp_lock.h>
00011 #include <linux/module.h>
00012 #ifdef CONFIG_RSBAC_LIST_TRANS_RANDOM_TA
00013 #include <linux/random.h>
00014 #endif
00015 #include <asm/uaccess.h>
00016 #include <rsbac/types.h>
00017 #include <rsbac/error.h>
00018 #include <rsbac/helpers.h>
00019 #include <rsbac/getname.h>
00020 #include <rsbac/debug.h>
00021 #include <rsbac/adf.h>
00022 #include <rsbac/aci_data_structures.h>
00023 #include <rsbac/proc_fs.h>
00024 #include <rsbac/rkmem.h>
00025 #include <rsbac/lists.h>
00026 #include <rsbac/gen_lists.h>
00027 
00028 /********************/
00029 /* Global Variables */
00030 /********************/
00031 
00032 static struct rsbac_list_reg_head_t       reg_head;
00033 static struct rsbac_list_lol_reg_head_t   lol_reg_head;
00034 static        rsbac_boolean_t             list_initialized = FALSE;
00035 
00036 #ifdef CONFIG_RSBAC_LIST_TRANS
00037 static struct rsbac_list_reg_item_t     * ta_handle = NULL;
00038 static        spinlock_t                  ta_lock = SPIN_LOCK_UNLOCKED;
00039 static        rsbac_boolean_t             ta_committing = FALSE;
00040 static        rsbac_boolean_t             ta_forgetting = FALSE;
00041 #ifndef CONFIG_RSBAC_LIST_TRANS_RANDOM_TA
00042               rsbac_list_ta_number_t      ta_next = 1;
00043 #endif
00044 #endif
00045 
00046 #ifdef CONFIG_RSBAC_LIST_TRANS
00047 static int do_forget(rsbac_list_ta_number_t ta_number);
00048 #endif
00049 
00050 #ifdef CONFIG_RSBAC_LIST_REPL
00051 static struct rsbac_nanotime_t repl_last;
00052 static struct rsbac_list_reg_item_t * repl_partner_handle = NULL;
00053 #endif
00054 
00055 
00056 /*********************************/
00057 /* Data Structures               */
00058 /*********************************/
00059 
00060 static struct rsbac_list_item_t * lookup_item_compare(
00061     struct rsbac_list_reg_item_t * list,
00062     void * desc)
00063     {
00064       struct rsbac_list_item_t  * curr;
00065 
00066       if(!list || !desc || !list->compare)
00067         return NULL;
00068 
00069       curr = list->curr;
00070       if(!curr)
00071         {
00072           curr = list->head;
00073           if(!curr)
00074             return NULL;
00075         }
00076       /* if current item is not the right one, search... */
00077       /* note: item desc is behind official struct */
00078       if(list->compare(desc, &curr[1]))
00079         {
00080           if((list->compare(desc, &curr[1]) > 0))
00081             {
00082               curr = curr->next;
00083               while (   curr
00084                      && (list->compare(desc, &curr[1]) > 0)
00085                     )
00086                 curr = curr->next;
00087             }
00088           else
00089             {
00090               curr = curr->prev;
00091               while (   curr
00092                      && (list->compare(desc, &curr[1]) < 0)
00093                     )
00094                 curr = curr->prev;
00095             }
00096           if (curr)
00097             {
00098               /* keep for speedup */
00099               list->curr = curr;
00100               if(!list->compare(desc, &curr[1]))
00101                 return curr;
00102             }
00103           /* NULL or not found */
00104           return NULL;
00105         }
00106       /* it is the current item -> return it */
00107       return curr;
00108     }
00109 
00110 static struct rsbac_list_item_t * lookup_item_memcmp(
00111     struct rsbac_list_reg_item_t * list,
00112     void * desc)
00113     {
00114       struct rsbac_list_item_t  * curr;
00115 
00116       if(!list || !desc)
00117         return NULL;
00118 
00119       curr = list->curr;
00120       if(!curr)
00121         {
00122           curr = list->head;
00123           if(!curr)
00124             return NULL;
00125         }
00126       /* if current item is not the right one, search... */
00127       /* note: item desc is behind official struct */
00128       if(memcmp(desc,
00129                 &curr[1],
00130                 list->info.desc_size))
00131         {
00132           if(memcmp(desc,
00133                     &curr[1],
00134                     list->info.desc_size) > 0)
00135             {
00136               curr = curr->next;
00137               while (   curr
00138                      && (memcmp(desc,
00139                                 &curr[1],
00140                                 list->info.desc_size) > 0)
00141                     )
00142                 curr = curr->next;
00143             }
00144           else
00145             {
00146               curr = curr->prev;
00147               while (   curr
00148                      && (memcmp(desc,
00149                                 &curr[1],
00150                                 list->info.desc_size) < 0)
00151                     )
00152                 curr = curr->prev;
00153             }
00154           if (curr)
00155             {
00156               /* keep for speedup */
00157               list->curr = curr;
00158               if(!memcmp(desc,
00159                          &curr[1],
00160                          list->info.desc_size))
00161                 return curr;
00162             }
00163           /* not found */
00164           return NULL;
00165         }
00166       /* it is the current item -> return it */
00167       return curr;
00168     }
00169 
00170 static struct rsbac_list_item_t * lookup_item(
00171     struct rsbac_list_reg_item_t * list,
00172     void * desc)
00173     {
00174       if(!list || !desc)
00175         return NULL;
00176 
00177       if(list->compare)
00178         return lookup_item_compare(list, desc);
00179       else
00180         return lookup_item_memcmp(list, desc);
00181     }
00182 
00183 #ifdef CONFIG_RSBAC_LIST_TRANS
00184 static struct rsbac_list_item_t * ta_lookup_item_compare(
00185     struct rsbac_list_reg_item_t * list,
00186     void * desc)
00187     {
00188       struct rsbac_list_item_t  * curr;
00189 
00190       if(!list || !desc || !list->compare)
00191         return NULL;
00192 
00193       curr = list->ta_curr;
00194       if(!curr)
00195         {
00196           curr = list->ta_head;
00197           if(!curr)
00198             return NULL;
00199         }
00200       /* if current item is not the right one, search... */
00201       /* note: item desc is behind official struct */
00202       if(list->compare(desc, &curr[1]))
00203         {
00204           if((list->compare(desc, &curr[1]) > 0))
00205             {
00206               curr = curr->next;
00207               while (   curr
00208                      && (list->compare(desc, &curr[1]) > 0)
00209                     )
00210                 curr = curr->next;
00211             }
00212           else
00213             {
00214               curr = curr->prev;
00215               while (   curr
00216                      && (list->compare(desc, &curr[1]) < 0)
00217                     )
00218                 curr = curr->prev;
00219             }
00220           if(curr)
00221             {
00222               /* keep for speedup */
00223               list->ta_curr = curr;
00224               if(!list->compare(desc, &curr[1]))
00225                 return curr;
00226             }
00227           /* NULL or not found */
00228           return NULL;
00229         }
00230       /* it is the current item -> return it */
00231       return curr;
00232     }
00233 
00234 static struct rsbac_list_item_t * ta_lookup_item_memcmp(
00235     struct rsbac_list_reg_item_t * list,
00236     void * desc)
00237     {
00238       struct rsbac_list_item_t  * curr;
00239 
00240       if(!list || !desc)
00241         return NULL;
00242 
00243       curr = list->ta_curr;
00244       if(!curr)
00245         {
00246           curr = list->ta_head;
00247           if(!curr)
00248             return NULL;
00249         }
00250       /* if current item is not the right one, search... */
00251       /* note: item desc is behind official struct */
00252       if(memcmp(desc,
00253                 &curr[1],
00254                 list->info.desc_size))
00255         {
00256           if(memcmp(desc,
00257                     &curr[1],
00258                     list->info.desc_size) > 0)
00259             {
00260               curr = curr->next;
00261               while (   curr
00262                      && (memcmp(desc,
00263                                 &curr[1],
00264                                 list->info.desc_size) > 0)
00265                     )
00266                 curr = curr->next;
00267             }
00268           else
00269             {
00270               curr = curr->prev;
00271               while (   curr
00272                      && (memcmp(desc,
00273                                 &curr[1],
00274                                 list->info.desc_size) < 0)
00275                     )
00276                 curr = curr->prev;
00277             }
00278           if (curr)
00279             {
00280               /* keep for speedup */
00281               list->ta_curr = curr;
00282               if(!memcmp(desc,
00283                          &curr[1],
00284                          list->info.desc_size))
00285                 return curr;
00286             }
00287           /* not found */
00288           return NULL;
00289         }
00290       /* it is the current item -> return it */
00291       return curr;
00292     }
00293 
00294 static struct rsbac_list_item_t * ta_lookup_item(
00295     rsbac_list_ta_number_t ta_number,
00296     struct rsbac_list_reg_item_t * list,
00297     void * desc)
00298     {
00299       if(!list || !desc)
00300         return NULL;
00301 
00302       if(!list->ta_copied)
00303         return lookup_item(list, desc);
00304       if(list->ta_copied != ta_number)
00305         return NULL;
00306 
00307       if(list->compare)
00308         return ta_lookup_item_compare(list, desc);
00309       else
00310         return ta_lookup_item_memcmp(list, desc);
00311     }
00312 #endif
00313 
00314 static struct rsbac_list_item_t * lookup_item_data_compare(
00315     struct rsbac_list_reg_item_t * list,
00316     void * data,
00317     rsbac_list_data_compare_function_t compare)
00318     {
00319       struct rsbac_list_item_t  * curr;
00320 
00321       if(!list || !data || !compare)
00322         return NULL;
00323 
00324       curr = list->head;
00325 
00326       /* note: item desc is behind official struct */
00327       while (   curr
00328              && (   (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00329                  || compare((char *)curr + sizeof(*curr) + list->info.desc_size, data)
00330                 )
00331             )
00332         curr = curr->next;
00333       /* it is the current item -> return it */
00334       return curr;
00335     }
00336 
00337 static struct rsbac_list_item_t * lookup_item_data_memcmp(
00338     struct rsbac_list_reg_item_t * list,
00339     void * data)
00340     {
00341       struct rsbac_list_item_t  * curr;
00342 
00343       if(!list || !data)
00344         return NULL;
00345 
00346       curr = list->head;
00347 
00348       /* note: item desc is behind official struct */
00349       while (   curr
00350              && (   (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00351                  || memcmp(data,
00352                            &curr[1] + list->info.desc_size,
00353                            list->info.data_size)
00354                 )
00355             )
00356         curr = curr->next;
00357       /* it is the current item -> return it */
00358       return curr;
00359     }
00360 
00361 static struct rsbac_list_item_t * lookup_item_data(
00362     struct rsbac_list_reg_item_t * list,
00363     void * data,
00364     rsbac_list_data_compare_function_t compare)
00365     {
00366       if(!list || !data)
00367         return NULL;
00368 
00369       if(compare)
00370         return lookup_item_data_compare(list, data, compare);
00371       else
00372         return lookup_item_data_memcmp(list, data);
00373     }
00374 
00375 #ifdef CONFIG_RSBAC_LIST_TRANS
00376 static struct rsbac_list_item_t * ta_lookup_item_data_compare(
00377     struct rsbac_list_reg_item_t * list,
00378     void * data,
00379     rsbac_list_data_compare_function_t compare)
00380     {
00381       struct rsbac_list_item_t  * curr;
00382 
00383       if(!list || !data || !compare)
00384         return NULL;
00385 
00386       curr = list->ta_head;
00387 
00388       /* note: item desc is behind official struct */
00389       while (   curr
00390              && (   (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00391                  || compare((char *)curr + sizeof(*curr) + list->info.desc_size, data)
00392                 )
00393             )
00394         curr = curr->next;
00395       /* it is the current item -> return it */
00396       return curr;
00397     }
00398 
00399 static struct rsbac_list_item_t * ta_lookup_item_data_memcmp(
00400     struct rsbac_list_reg_item_t * list,
00401     void * data)
00402     {
00403       struct rsbac_list_item_t  * curr;
00404 
00405       if(!list || !data)
00406         return NULL;
00407 
00408       curr = list->ta_head;
00409 
00410       /* note: item desc is behind official struct */
00411       while (   curr
00412              && (   (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00413                  || memcmp(data,
00414                            &curr[1] + list->info.desc_size,
00415                            list->info.data_size)
00416                 )
00417             )
00418         curr = curr->next;
00419       /* it is the current item -> return it */
00420       return curr;
00421     }
00422 
00423 static struct rsbac_list_item_t * ta_lookup_item_data(
00424     rsbac_list_ta_number_t ta_number,
00425     struct rsbac_list_reg_item_t * list,
00426     void * data,
00427     rsbac_list_data_compare_function_t compare)
00428     {
00429       if(!list || !data)
00430         return NULL;
00431 
00432       if(!list->ta_copied || list->ta_copied != ta_number)
00433         return lookup_item_data(list, data, compare);
00434 
00435       if(compare)
00436         return ta_lookup_item_data_compare(list, data, compare);
00437       else
00438         return ta_lookup_item_data_memcmp(list, data);
00439     }
00440 #endif
00441 
00442 /* list of lists - subitems */
00443 
00444 static struct rsbac_list_item_t * lookup_lol_subitem_compare(
00445     struct rsbac_list_lol_reg_item_t * list,
00446     struct rsbac_list_lol_item_t * sublist,
00447     void * subdesc,
00448     rsbac_list_compare_function_t compare)
00449     {
00450       struct rsbac_list_item_t  * curr;
00451 
00452       if(!list || !sublist || !subdesc || !compare)
00453         return NULL;
00454 
00455       curr = sublist->curr;
00456       if(!curr)
00457         {
00458           curr = sublist->head;
00459           if(!curr)
00460             return NULL;
00461         }
00462       /* if current item is not the right one, search... */
00463       /* note: item desc is behind official struct */
00464       if(compare(&curr[1],subdesc))
00465         {
00466           if((compare(&curr[1], subdesc) < 0))
00467             {
00468               curr = curr->next;
00469               while (   curr
00470                      && (compare(&curr[1], subdesc) < 0)
00471                     )
00472                 curr = curr->next;
00473             }
00474           else
00475             {
00476               curr = curr->prev;
00477               while (   curr
00478                      && (compare(&curr[1], subdesc) > 0)
00479                     )
00480                 curr = curr->prev;
00481             }
00482           if (curr)
00483             {
00484               /* keep for speedup */
00485               sublist->curr = curr;
00486               if(!compare(&curr[1], subdesc))
00487                 return curr;
00488             }
00489           /* not found */
00490           return NULL;
00491         }
00492       /* it is the current item -> return it */
00493       return curr;
00494     }
00495 
00496 static struct rsbac_list_item_t * lookup_lol_subitem_memcmp(
00497     struct rsbac_list_lol_reg_item_t * list,
00498     struct rsbac_list_lol_item_t * sublist,
00499     void * subdesc)
00500     {
00501       struct rsbac_list_item_t  * curr;
00502 
00503       if(!list || !sublist || !subdesc)
00504         return NULL;
00505 
00506       curr = sublist->curr;
00507       if(!curr)
00508         {
00509           curr = sublist->head;
00510           if(!curr)
00511             return NULL;
00512         }
00513       /* if current item is not the right one, search... */
00514       /* note: item desc is behind official struct */
00515       if(memcmp(subdesc,
00516                 &curr[1],
00517                 list->info.subdesc_size))
00518         {
00519           if(memcmp(subdesc,
00520                     &curr[1],
00521                     list->info.subdesc_size) > 0)
00522             {
00523               curr = curr->next;
00524               while (   curr
00525                      && (memcmp(subdesc,
00526                                 &curr[1],
00527                                 list->info.subdesc_size) > 0)
00528                     )
00529                 curr = curr->next;
00530             }
00531           else
00532             {
00533               curr = curr->prev;
00534               while (   curr
00535                      && (memcmp(subdesc,
00536                                 &curr[1],
00537                                 list->info.subdesc_size) < 0)
00538                     )
00539                 curr = curr->prev;
00540             }
00541           if (curr)
00542             {
00543               /* keep for speedup */
00544               sublist->curr = curr;
00545               if(!memcmp(subdesc,
00546                          &curr[1],
00547                          list->info.subdesc_size))
00548                 return curr;
00549             }
00550           /* not found */
00551           return NULL;
00552         }
00553       /* it is the current item -> return it */
00554       return curr;
00555     }
00556 
00557 static struct rsbac_list_item_t * lookup_lol_subitem(
00558     struct rsbac_list_lol_reg_item_t * list,
00559     struct rsbac_list_lol_item_t * sublist,
00560     void * subdesc)
00561     {
00562       if(!list || !sublist || !subdesc)
00563         return NULL;
00564 
00565       if(list->subcompare)
00566         return lookup_lol_subitem_compare(list, sublist, subdesc, list->subcompare);
00567       else
00568         return lookup_lol_subitem_memcmp(list, sublist, subdesc);
00569     }
00570 
00571 static struct rsbac_list_item_t * lookup_lol_subitem_user_compare(
00572     struct rsbac_list_lol_reg_item_t * list,
00573     struct rsbac_list_lol_item_t * sublist,
00574     void * subdesc,
00575     rsbac_list_compare_function_t compare)
00576     {
00577       struct rsbac_list_item_t  * curr;
00578 
00579       if(!list || !sublist || !subdesc || !compare)
00580         return NULL;
00581 
00582       curr = sublist->head;
00583       /* note: item desc is behind official struct */
00584       while(curr)
00585         {
00586           if(!compare(&curr[1],subdesc))
00587             return curr;
00588           curr = curr->next;
00589         }
00590       return curr;
00591     }
00592 
00593 /* list of lists - items */
00594 
00595 static struct rsbac_list_lol_item_t * lookup_lol_item_compare(
00596     struct rsbac_list_lol_reg_item_t * list,
00597     void * desc)
00598     {
00599       struct rsbac_list_lol_item_t  * curr;
00600 
00601       if(!list || !desc || !list->compare)
00602         return NULL;
00603 
00604       curr = list->curr;
00605       if(!curr)
00606         {
00607           curr = list->head;
00608           if(!curr)
00609             return NULL;
00610         }
00611       /* if current item is not the right one, search... */
00612       /* note: item desc is behind official struct */
00613       if(list->compare(desc, &curr[1]))
00614         {
00615           if((list->compare(desc, &curr[1]) > 0))
00616             {
00617               curr = curr->next;
00618               while (   curr
00619                      && (list->compare(desc, &curr[1]) > 0)
00620                     )
00621                 curr = curr->next;
00622             }
00623           else
00624             {
00625               curr = curr->prev;
00626               while (   curr
00627                      && (list->compare(desc, &curr[1]) < 0)
00628                     )
00629                 curr = curr->prev;
00630             }
00631           if (curr)
00632             {
00633               /* keep for speedup */
00634               list->curr = curr;
00635               if(!list->compare(desc, &curr[1]))
00636                 return curr;
00637             }
00638           /* not found */
00639           return NULL;
00640         }
00641       /* it is the current item -> return it */
00642       return curr;
00643     }
00644 
00645 static struct rsbac_list_lol_item_t * lookup_lol_item_memcmp(
00646     struct rsbac_list_lol_reg_item_t * list,
00647     void * desc)
00648     {
00649       struct rsbac_list_lol_item_t  * curr;
00650 
00651       if(!list || !desc)
00652         return NULL;
00653 
00654       curr = list->curr;
00655       if(!curr)
00656         {
00657           curr = list->head;
00658           if(!curr)
00659             return NULL;
00660         }
00661       /* if current item is not the right one, search... */
00662       /* note: item desc is behind official struct */
00663       if(memcmp(desc,
00664                 &curr[1],
00665                 list->info.desc_size))
00666         {
00667           if(memcmp(desc,
00668                     &curr[1],
00669                     list->info.desc_size) > 0)
00670             {
00671               curr = curr->next;
00672               while (   curr
00673                      && (memcmp(desc,
00674                                 &curr[1],
00675                                 list->info.desc_size) > 0)
00676                     )
00677                 curr = curr->next;
00678             }
00679           else
00680             {
00681               curr = curr->prev;
00682               while (   curr
00683                      && (memcmp(desc,
00684                                 &curr[1],
00685                                 list->info.desc_size) < 0)
00686                     )
00687                 curr = curr->prev;
00688             }
00689           if (curr)
00690             {
00691               /* keep for speedup */
00692               list->curr = curr;
00693               if(!memcmp(desc,
00694                          &curr[1],
00695                          list->info.desc_size))
00696                 return curr;
00697             }
00698           /* not found */
00699           return NULL;
00700         }
00701       /* it is the current item -> return it */
00702       return curr;
00703     }
00704 
00705 static struct rsbac_list_lol_item_t * lookup_lol_item(
00706     struct rsbac_list_lol_reg_item_t * list,
00707     void * desc)
00708     {
00709       if(!list || !desc)
00710         return NULL;
00711 
00712       if(list->compare)
00713         return lookup_lol_item_compare(list, desc);
00714       else
00715         return lookup_lol_item_memcmp(list, desc);
00716     }
00717 
00718 #ifdef CONFIG_RSBAC_LIST_TRANS
00719 static struct rsbac_list_lol_item_t * ta_lookup_lol_item_compare(
00720     struct rsbac_list_lol_reg_item_t * list,
00721     void * desc)
00722     {
00723       struct rsbac_list_lol_item_t  * curr;
00724 
00725       if(!list || !desc || !list->compare)
00726         return NULL;
00727 
00728       curr = list->ta_curr;
00729       if(!curr)
00730         {
00731           curr = list->ta_head;
00732           if(!curr)
00733             return NULL;
00734         }
00735       /* if current item is not the right one, search... */
00736       /* note: item desc is behind official struct */
00737       if(list->compare(desc, &curr[1]))
00738         {
00739           if((list->compare(desc, &curr[1]) > 0))
00740             {
00741               curr = curr->next;
00742               while (   curr
00743                      && (list->compare(desc, &curr[1]) > 0)
00744                     )
00745                 curr = curr->next;
00746             }
00747           else
00748             {
00749               curr = curr->prev;
00750               while (   curr
00751                      && (list->compare(desc, &curr[1]) < 0)
00752                     )
00753                 curr = curr->prev;
00754             }
00755           if (curr)
00756             {
00757               /* keep for speedup */
00758               list->ta_curr = curr;
00759               if(!list->compare(desc, &curr[1]))
00760                 return curr;
00761             }
00762           /* not found */
00763           return NULL;
00764         }
00765       /* it is the current item -> return it */
00766       return curr;
00767     }
00768 
00769 static struct rsbac_list_lol_item_t * ta_lookup_lol_item_memcmp(
00770     struct rsbac_list_lol_reg_item_t * list,
00771     void * desc)
00772     {
00773       struct rsbac_list_lol_item_t  * curr;
00774 
00775       if(!list || !desc)
00776         return NULL;
00777 
00778       curr = list->ta_curr;
00779       if(!curr)
00780         {
00781           curr = list->ta_head;
00782           if(!curr)
00783             return NULL;
00784         }
00785       /* if current item is not the right one, search... */
00786       /* note: item desc is behind official struct */
00787       if(memcmp(desc,
00788                 &curr[1],
00789                 list->info.desc_size))
00790         {
00791           if(memcmp(desc,
00792                     &curr[1],
00793                     list->info.desc_size) > 0)
00794             {
00795               curr = curr->next;
00796               while (   curr
00797                      && (memcmp(desc,
00798                                 &curr[1],
00799                                 list->info.desc_size) > 0)
00800                     )
00801                 curr = curr->next;
00802             }
00803           else
00804             {
00805               curr = curr->prev;
00806               while (   curr
00807                      && (memcmp(desc,
00808                                 &curr[1],
00809                                 list->info.desc_size) < 0)
00810                     )
00811                 curr = curr->prev;
00812             }
00813           if (curr)
00814             {
00815               /* keep for speedup */
00816               list->ta_curr = curr;
00817               if(!memcmp(desc,
00818                          &curr[1],
00819                          list->info.desc_size))
00820                 return curr;
00821             }
00822           /* not found */
00823           return NULL;
00824         }
00825       /* it is the current item -> return it */
00826       return curr;
00827     }
00828 
00829 static struct rsbac_list_lol_item_t * ta_lookup_lol_item(
00830     rsbac_list_ta_number_t ta_number,
00831     struct rsbac_list_lol_reg_item_t * list,
00832     void * desc)
00833     {
00834       if(!list || !desc)
00835         return NULL;
00836 
00837       if(!list->ta_copied)
00838         return lookup_lol_item(list, desc);
00839       if(list->ta_copied != ta_number)
00840         return NULL;
00841 
00842       if(list->compare)
00843         return ta_lookup_lol_item_compare(list, desc);
00844       else
00845         return ta_lookup_lol_item_memcmp(list, desc);
00846     }
00847 #endif
00848 
00849 static struct rsbac_list_lol_item_t * lookup_lol_item_data_compare(
00850     struct rsbac_list_lol_reg_item_t * list,
00851     void * data,
00852     rsbac_list_data_compare_function_t compare)
00853     {
00854       struct rsbac_list_lol_item_t  * curr;
00855 
00856       if(!list || !data || !compare)
00857         return NULL;
00858 
00859       curr = list->head;
00860 
00861       /* note: item desc is behind official struct */
00862       while (   curr
00863              && (   (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00864                  || compare((char *)curr + sizeof(*curr) + list->info.desc_size, data)
00865                 )
00866             )
00867         curr = curr->next;
00868       /* it is the current item -> return it */
00869       return curr;
00870     }
00871 
00872 static struct rsbac_list_lol_item_t * lookup_lol_item_data_memcmp(
00873     struct rsbac_list_lol_reg_item_t * list,
00874     void * data)
00875     {
00876       struct rsbac_list_lol_item_t  * curr;
00877 
00878       if(!list || !data)
00879         return NULL;
00880 
00881       curr = list->head;
00882 
00883       /* note: item desc is behind official struct */
00884       while (   curr
00885              && (   (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00886                  || memcmp(data,
00887                            &curr[1] + list->info.desc_size,
00888                            list->info.data_size)
00889                 )
00890             )
00891         curr = curr->next;
00892       /* it is the current item -> return it */
00893       return curr;
00894     }
00895 
00896 static struct rsbac_list_lol_item_t * lookup_lol_item_data(
00897     struct rsbac_list_lol_reg_item_t * list,
00898     void * data,
00899     rsbac_list_data_compare_function_t compare)
00900     {
00901       if(!list || !data)
00902         return NULL;
00903 
00904       if(compare)
00905         return lookup_lol_item_data_compare(list, data, compare);
00906       else
00907         return lookup_lol_item_data_memcmp(list, data);
00908     }
00909 
00910 #ifdef CONFIG_RSBAC_LIST_TRANS
00911 static struct rsbac_list_lol_item_t * ta_lookup_lol_item_data_compare(
00912     struct rsbac_list_lol_reg_item_t * list,
00913     void * data,
00914     rsbac_list_data_compare_function_t compare)
00915     {
00916       struct rsbac_list_lol_item_t  * curr;
00917 
00918       if(!list || !data || !compare)
00919         return NULL;
00920 
00921       curr = list->ta_head;
00922 
00923       /* note: item desc is behind official struct */
00924       while (   curr
00925              && (   (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00926                  || compare((char *)curr + sizeof(*curr) + list->info.desc_size, data)
00927                 )
00928             )
00929         curr = curr->next;
00930       /* it is the current item -> return it */
00931       return curr;
00932     }
00933 
00934 static struct rsbac_list_lol_item_t * ta_lookup_lol_item_data_memcmp(
00935     struct rsbac_list_lol_reg_item_t * list,
00936     void * data)
00937     {
00938       struct rsbac_list_lol_item_t  * curr;
00939 
00940       if(!list || !data)
00941         return NULL;
00942 
00943       curr = list->ta_head;
00944 
00945       /* note: item desc is behind official struct */
00946       while (   curr
00947              && (   (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00948                  || memcmp(data,
00949                            &curr[1] + list->info.desc_size,
00950                            list->info.data_size)
00951                 )
00952             )
00953         curr = curr->next;
00954       /* it is the current item -> return it */
00955       return curr;
00956     }
00957 
00958 static struct rsbac_list_lol_item_t * ta_lookup_lol_item_data(
00959     rsbac_list_ta_number_t ta_number,
00960     struct rsbac_list_lol_reg_item_t * list,
00961     void * data,
00962     rsbac_list_data_compare_function_t compare)
00963     {
00964       if(!list || !data)
00965         return NULL;
00966 
00967       if(!list->ta_copied || list->ta_copied != ta_number)
00968         return lookup_lol_item_data(list, data, compare);
00969 
00970       if(compare)
00971         return ta_lookup_lol_item_data_compare(list, data, compare);
00972       else
00973         return ta_lookup_lol_item_data_memcmp(list, data);
00974     }
00975 #endif
00976 
00977 /* Registration lookup */
00978 
00979 static struct rsbac_list_reg_item_t * lookup_reg(struct rsbac_list_reg_item_t *  handle)
00980     {
00981       struct rsbac_list_reg_item_t  * curr = reg_head.curr;
00982       
00983       if(!handle)
00984         return NULL;
00985       /* if there is no current item or it is not the right one, search... */
00986       if(curr != handle)
00987         {
00988           curr = reg_head.head;
00989           while (curr && curr != handle)
00990             curr = curr->next;
00991           if (curr)
00992             reg_head.curr=curr;
00993 #ifdef CONFIG_RSBAC_DEBUG
00994           else
00995             if(rsbac_debug_lists)
00996               {
00997                 rsbac_printk(KERN_DEBUG "lookup_reg(): Lookup of unknown list handle %p\n",
00998                        handle);
00999               }
01000 #endif
01001         }
01002       /* it is the current item -> return it */
01003       return curr;
01004     }
01005 
01006 static struct rsbac_list_reg_item_t * lookup_reg_name(char * name, kdev_t device)
01007     {
01008       struct rsbac_list_reg_item_t  * curr = reg_head.curr;
01009       
01010       if(!name)
01011         return NULL;
01012       /* if there is no current item or it is not the right one, search... */
01013       if(   !curr
01014          || (   strncmp(curr->name, name, RSBAC_LIST_MAX_FILENAME)
01015              || (RSBAC_MAJOR(curr->device) != RSBAC_MAJOR(device))
01016              || (RSBAC_MINOR(curr->device) != RSBAC_MINOR(device))
01017             )
01018         )
01019         {
01020           curr = reg_head.head;
01021           while (   curr
01022                  && (   strncmp(curr->name, name, RSBAC_LIST_MAX_FILENAME)
01023                      || (RSBAC_MAJOR(curr->device) != RSBAC_MAJOR(device))
01024                      || (RSBAC_MINOR(curr->device) != RSBAC_MINOR(device))
01025                     )
01026                 )
01027             curr = curr->next;
01028           if (curr)
01029             reg_head.curr=curr;
01030 #ifdef CONFIG_RSBAC_DEBUG
01031           else
01032             if(rsbac_debug_lists)
01033               {
01034                 rsbac_printk(KERN_DEBUG "lookup_reg_name(): Lookup of unknown list name %s on device %02u:%02u\n",
01035                        name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
01036               }
01037 #endif
01038         }
01039       /* it is the current item -> return it */
01040       return curr;
01041     }
01042 
01043 /* List of lists registration lookup */
01044 
01045 static struct rsbac_list_lol_reg_item_t * lookup_lol_reg(struct rsbac_list_lol_reg_item_t *  handle)
01046     {
01047       struct rsbac_list_lol_reg_item_t  * curr = lol_reg_head.curr;
01048       
01049       if(!handle)
01050         return NULL;
01051       /* if there is no current item or it is not the right one, search... */
01052       if(curr != handle)
01053         {
01054           curr = lol_reg_head.head;
01055           while (curr && curr != handle)
01056             curr = curr->next;
01057           if (curr)
01058             lol_reg_head.curr=curr;
01059 #ifdef CONFIG_RSBAC_DEBUG
01060           else
01061             if(rsbac_debug_lists)
01062               {
01063                 rsbac_printk(KERN_DEBUG "lookup_lol_reg(): Lookup of unknown list handle %p\n",
01064                        handle);
01065               }
01066 #endif
01067         }
01068       /* it is the current item -> return it */
01069       return curr;
01070     }
01071 
01072 static struct rsbac_list_lol_reg_item_t * lookup_lol_reg_name(char * name, kdev_t device)
01073     {
01074       struct rsbac_list_lol_reg_item_t  * curr = lol_reg_head.curr;
01075       
01076       if(!name)
01077         return NULL;
01078       /* if there is no current item or it is not the right one, search... */
01079       if(   !curr
01080          || (   strncmp(curr->name, name, RSBAC_LIST_MAX_FILENAME)
01081              || (RSBAC_MAJOR(curr->device) != RSBAC_MAJOR(device))
01082              || (RSBAC_MINOR(curr->device) != RSBAC_MINOR(device))
01083             )
01084         )
01085         {
01086           curr = lol_reg_head.head;
01087           while (   curr
01088                  && (   strncmp(curr->name, name, RSBAC_LIST_MAX_FILENAME)
01089                      || (RSBAC_MAJOR(curr->device) != RSBAC_MAJOR(device))
01090                      || (RSBAC_MINOR(curr->device) != RSBAC_MINOR(device))
01091                     )
01092                 )
01093             curr = curr->next;
01094           if (curr)
01095             lol_reg_head.curr=curr;
01096 #ifdef CONFIG_RSBAC_DEBUG
01097           else
01098             if(rsbac_debug_lists)
01099               {
01100                 rsbac_printk(KERN_DEBUG "lookup_lol_reg_name(): Lookup of unknown list name %s on device %02u:%02u\n",
01101                        name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
01102               }
01103 #endif
01104         }
01105       /* it is the current item -> return it */
01106       return curr;
01107     }
01108 
01109 /*************/
01110 /* Add items */
01111 
01112 static struct rsbac_list_item_t * insert_item_compare(
01113     struct rsbac_list_reg_item_t * list,
01114     void * desc,
01115     struct rsbac_list_item_t * new_item_p)
01116     {
01117       struct rsbac_list_item_t * curr;
01118 
01119       curr = list->curr;
01120       if(!curr)
01121         curr = list->head;
01122       if((list->compare(desc, &curr[1]) > 0))
01123         {
01124           curr = curr->next;
01125           while (   curr
01126                  && (list->compare(desc, &curr[1]) > 0)
01127                 )
01128             curr = curr->next;
01129           if (curr)
01130             {
01131               /* insert before curr */
01132               new_item_p->prev=curr->prev;
01133               new_item_p->next=curr;
01134               curr->prev->next=new_item_p;
01135               curr->prev=new_item_p;
01136             }
01137           else
01138             {
01139               /* insert as last item */
01140               new_item_p->prev=list->tail;
01141               new_item_p->next=NULL;
01142               list->tail->next=new_item_p;
01143               list->tail=new_item_p;
01144             }
01145         }
01146       else
01147         {
01148           curr = curr->prev;
01149           while (   curr
01150                  && (list->compare(desc, &curr[1]) < 0)
01151                 )
01152             curr = curr->prev;
01153           if (curr)
01154             {
01155               /* insert after curr */
01156               new_item_p->prev=curr;
01157               new_item_p->next=curr->next;
01158               curr->next->prev=new_item_p;
01159               curr->next=new_item_p;
01160             }
01161           else
01162             {
01163               /* insert as first item */
01164               new_item_p->prev=NULL;
01165               new_item_p->next=list->head;
01166               list->head->prev=new_item_p;
01167               list->head=new_item_p;
01168             }
01169         }
01170       list->count++;
01171       list->curr=new_item_p;
01172       return new_item_p;
01173     }
01174 
01175 static struct rsbac_list_item_t * insert_item_memcmp(
01176     struct rsbac_list_reg_item_t * list,
01177     void * desc,
01178     struct rsbac_list_item_t * new_item_p)
01179     {
01180       struct rsbac_list_item_t * curr;
01181 
01182       curr = list->curr;
01183       if(!curr)
01184         curr = list->head;
01185       if(memcmp(desc,
01186                 &curr[1],
01187                 list->info.desc_size) > 0)
01188         {
01189           curr = curr->next;
01190           while (   curr
01191                  && (memcmp(desc,
01192                            &curr[1],
01193                            list->info.desc_size) > 0
01194                     )
01195                 )
01196             curr = curr->next;
01197           if (curr)
01198             {
01199               /* insert before curr */
01200               new_item_p->prev=curr->prev;
01201               new_item_p->next=curr;
01202               curr->prev->next=new_item_p;
01203               curr->prev=new_item_p;
01204             }
01205           else
01206             {
01207               /* insert as last item */
01208               new_item_p->prev=list->tail;
01209               new_item_p->next=NULL;
01210               list->tail->next=new_item_p;
01211               list->tail=new_item_p;
01212             }
01213         }
01214       else
01215         {
01216           curr = curr->prev;
01217           while (   curr
01218                  && (memcmp(desc,
01219                            &curr[1],
01220                            list->info.desc_size) < 0
01221                     )
01222                 )
01223             curr = curr->prev;
01224           if (curr)
01225             {
01226               /* insert after curr */
01227               new_item_p->prev=curr;
01228               new_item_p->next=curr->next;
01229               curr->next->prev=new_item_p;
01230               curr->next=new_item_p;
01231             }
01232           else
01233             {
01234               /* insert as first item */
01235               new_item_p->prev=NULL;
01236               new_item_p->next=list->head;
01237               list->head->prev=new_item_p;
01238               list->head=new_item_p;
01239             }
01240         }
01241       list->count++;
01242       list->curr=new_item_p;
01243       return new_item_p;
01244     }
01245 
01246 static struct rsbac_list_item_t * add_item(
01247     struct rsbac_list_reg_item_t * list,
01248     rsbac_time_t max_age,
01249     void * desc,
01250     void * data)
01251     {
01252       struct rsbac_list_item_t * new_item_p = NULL;
01253 
01254       if(!list || !desc)
01255         return NULL;
01256 
01257       if(!list || !desc)
01258         return NULL;
01259       if(list->info.data_size && !data)
01260         return NULL;
01261       /* item desc and data are behind official struct */
01262       if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p) + list->info.desc_size + list->info.data_size)) )
01263         return(NULL);
01264       new_item_p->max_age = max_age;
01265       /* item desc is behind official struct */
01266       memcpy(&new_item_p[1],
01267              desc, list->info.desc_size);
01268       /* item data is behind official struct and desc */
01269       /* data might be empty! */
01270       if(data && list->info.data_size)
01271         memcpy(((__u8 *) new_item_p) + sizeof(*new_item_p) + list->info.desc_size,
01272                data,
01273                list->info.data_size);
01274 
01275       if (!list->head)
01276         {
01277           list->head=new_item_p;
01278           list->tail=new_item_p;
01279           list->curr=new_item_p;
01280           list->count = 1;
01281           new_item_p->prev=NULL;
01282           new_item_p->next=NULL;
01283           return new_item_p;
01284         }
01285       if(list->compare)
01286         return insert_item_compare(list, desc, new_item_p);
01287       else
01288         return insert_item_memcmp(list, desc, new_item_p);
01289     }
01290 
01291 #ifdef CONFIG_RSBAC_LIST_TRANS
01292 static void ta_remove_all_items(struct rsbac_list_reg_item_t * list);
01293 
01294 static int ta_copy(
01295   rsbac_list_ta_number_t ta_number,
01296   struct rsbac_list_reg_item_t * list)
01297   {
01298     struct rsbac_list_item_t * curr;
01299     struct rsbac_list_item_t * new_item_p;
01300     u_int item_size =   sizeof(*new_item_p)
01301                       + list->info.desc_size
01302                       + list->info.data_size;
01303 
01304     curr = list->head;
01305     if(curr)
01306       {
01307         if ( !(new_item_p = rsbac_kmalloc(item_size) ))
01308           {
01309             ta_remove_all_items(list);
01310             return(-RSBAC_ENOMEM);
01311           }
01312         memcpy(new_item_p, curr, item_size);
01313         new_item_p->prev = NULL;
01314         new_item_p->next = NULL;
01315         list->ta_head = new_item_p;
01316         list->ta_tail = new_item_p;
01317         list->ta_curr = new_item_p;
01318         list->ta_count = 1;
01319         curr = curr->next;
01320       }
01321     else
01322       {
01323         list->ta_head = NULL;
01324         list->ta_tail = NULL;
01325         list->ta_curr = NULL;
01326         list->ta_count = 0;
01327         list->ta_copied = ta_number;
01328         return 0;
01329       }
01330     while(curr)
01331       {
01332         if ( !(new_item_p = rsbac_kmalloc(item_size)) )
01333           {
01334             ta_remove_all_items(list);
01335             return(-RSBAC_ENOMEM);
01336           }
01337         memcpy(new_item_p, curr, item_size);
01338         new_item_p->prev = list->ta_tail;
01339         new_item_p->next = NULL;
01340         list->ta_tail->next = new_item_p;
01341         list->ta_tail = new_item_p;
01342         list->ta_count++;
01343         curr = curr->next;
01344       }
01345     list->ta_copied = ta_number;
01346     return 0;
01347   }
01348 
01349 static void ta_remove_all_lol_items(struct rsbac_list_lol_reg_item_t * list);
01350 
01351 static int ta_lol_copy(
01352   rsbac_list_ta_number_t ta_number,
01353   struct rsbac_list_lol_reg_item_t * list)
01354   {
01355     struct rsbac_list_lol_item_t * curr;
01356     struct rsbac_list_lol_item_t * new_item_p;
01357     struct rsbac_list_item_t * sub_curr;
01358     struct rsbac_list_item_t * new_subitem_p;
01359     u_int item_size =   sizeof(*new_item_p)
01360                       + list->info.desc_size
01361                       + list->info.data_size;
01362     u_int subitem_size =   sizeof(*new_subitem_p)
01363                          + list->info.subdesc_size
01364                          + list->info.subdata_size;
01365 
01366     list->ta_head = NULL;
01367     list->ta_tail = NULL;
01368     list->ta_curr = NULL;
01369     list->ta_count = 0;
01370 
01371     curr = list->head;
01372     while(curr)
01373       {
01374         if ( !(new_item_p = rsbac_kmalloc(item_size)) )
01375           {
01376             ta_remove_all_lol_items(list);
01377             return(-RSBAC_ENOMEM);
01378           }
01379         memcpy(new_item_p, curr, item_size);
01380         new_item_p->head = NULL;
01381         new_item_p->tail = NULL;
01382         new_item_p->curr = NULL;
01383         new_item_p->count = 0;
01384         new_item_p->prev = NULL;
01385         new_item_p->next = NULL;
01386         sub_curr = curr->head;
01387         while(sub_curr)
01388           {
01389             if ( !(new_subitem_p = rsbac_kmalloc(subitem_size)) )
01390               {
01391                 ta_remove_all_lol_items(list);
01392                 rsbac_kfree(new_item_p);
01393                 return(-RSBAC_ENOMEM);
01394               }
01395             memcpy(new_subitem_p, sub_curr, subitem_size);
01396             new_subitem_p->prev = NULL;
01397             new_subitem_p->next = NULL;
01398             if(new_item_p->tail)
01399               {
01400                 new_subitem_p->prev = new_item_p->tail;
01401                 new_item_p->tail->next = new_subitem_p;
01402                 new_item_p->tail = new_subitem_p;
01403                 new_item_p->count++;
01404               }
01405             else
01406               {
01407                 new_item_p->head = new_subitem_p;
01408                 new_item_p->tail = new_subitem_p;
01409                 new_item_p->count = 1;
01410               }
01411             sub_curr = sub_curr->next;
01412           }
01413         if(list->ta_tail)
01414           {
01415             new_item_p->prev = list->ta_tail;
01416             list->ta_tail->next = new_item_p;
01417             list->ta_tail = new_item_p;
01418             list->ta_count++;
01419           }
01420         else
01421           {
01422             list->ta_head = new_item_p;
01423             list->ta_tail = new_item_p;
01424             list->ta_curr = new_item_p;
01425             list->ta_count = 1;
01426           }
01427         curr = curr->next;
01428       }
01429     list->ta_copied = ta_number;
01430     return 0;
01431   }
01432 
01433 static struct rsbac_list_item_t * ta_insert_item_compare(
01434     struct rsbac_list_reg_item_t * list,
01435     void * desc,
01436     struct rsbac_list_item_t * new_item_p)
01437     {
01438       struct rsbac_list_item_t * curr;
01439 
01440       curr = list->ta_curr;
01441       if(!curr)
01442         curr = list->ta_head;
01443       if((list->compare(desc, &curr[1]) > 0))
01444         {
01445           curr = curr->next;
01446           while (   curr
01447                  && (list->compare(desc, &curr[1]) > 0)
01448                 )
01449             curr = curr->next;
01450           if (curr)
01451             {
01452               /* insert before curr */
01453               new_item_p->prev=curr->prev;
01454               new_item_p->next=curr;
01455               curr->prev->next=new_item_p;
01456               curr->prev=new_item_p;
01457             }
01458           else
01459             {
01460               /* insert as last item */
01461               new_item_p->prev=list->ta_tail;
01462               new_item_p->next=NULL;
01463               list->ta_tail->next=new_item_p;
01464               list->ta_tail=new_item_p;
01465             }
01466         }
01467       else
01468         {
01469           curr = curr->prev;
01470           while (   curr
01471                  && (list->compare(desc, &curr[1]) < 0)
01472                 )
01473             curr = curr->prev;
01474           if (curr)
01475             {
01476               /* insert after curr */
01477               new_item_p->prev=curr;
01478               new_item_p->next=curr->next;
01479               curr->next->prev=new_item_p;
01480               curr->next=new_item_p;
01481             }
01482           else
01483             {
01484               /* insert as first item */
01485               new_item_p->prev=NULL;
01486               new_item_p->next=list->ta_head;
01487               list->ta_head->prev=new_item_p;
01488               list->ta_head=new_item_p;
01489             }
01490         }
01491       list->ta_count++;
01492       list->ta_curr=new_item_p;
01493       return new_item_p;
01494     }
01495 
01496 static struct rsbac_list_item_t * ta_insert_item_memcmp(
01497     struct rsbac_list_reg_item_t * list,
01498     void * desc,
01499     struct rsbac_list_item_t * new_item_p)
01500     {
01501       struct rsbac_list_item_t * curr;
01502 
01503       curr = list->ta_curr;
01504       if(!curr)
01505         curr = list->ta_head;
01506       if(memcmp(desc,
01507                 &curr[1],
01508                 list->info.desc_size) > 0)
01509         {
01510           curr = curr->next;
01511           while (   curr
01512                  && (memcmp(desc,
01513                            &curr[1],
01514                            list->info.desc_size) > 0
01515                     )
01516                 )
01517             curr = curr->next;
01518           if (curr)
01519             {
01520               /* insert before curr */
01521               new_item_p->prev=curr->prev;
01522               new_item_p->next=curr;
01523               curr->prev->next=new_item_p;
01524               curr->prev=new_item_p;
01525             }
01526           else
01527             {
01528               /* insert as last item */
01529               new_item_p->prev=list->ta_tail;
01530               new_item_p->next=NULL;
01531               list->ta_tail->next=new_item_p;
01532               list->ta_tail=new_item_p;
01533             }
01534         }
01535       else
01536         {
01537           curr = curr->prev;
01538           while (   curr
01539                  && (memcmp(desc,
01540                            &curr[1],
01541                            list->info.desc_size) < 0
01542                     )
01543                 )
01544             curr = curr->prev;
01545           if (curr)
01546             {
01547               /* insert after curr */
01548               new_item_p->prev=curr;
01549               new_item_p->next=curr->next;
01550               curr->next->prev=new_item_p;
01551               curr->next=new_item_p;
01552             }
01553           else
01554             {
01555               /* insert as first item */
01556               new_item_p->prev=NULL;
01557               new_item_p->next=list->ta_head;
01558               list->ta_head->prev=new_item_p;
01559               list->ta_head=new_item_p;
01560             }
01561         }
01562       list->ta_count++;
01563       list->ta_curr=new_item_p;
01564       return new_item_p;
01565     }
01566 
01567 static struct rsbac_list_item_t * ta_add_item(
01568     rsbac_list_ta_number_t ta_number,
01569     struct rsbac_list_reg_item_t * list,
01570     rsbac_time_t max_age,
01571     void * desc,
01572     void * data)
01573     {
01574       struct rsbac_list_item_t * new_item_p = NULL;
01575 
01576       if(!list || !desc)
01577         return NULL;
01578 
01579       if(!list || !desc)
01580         return NULL;
01581       if(list->info.data_size && !data)
01582         return NULL;
01583       if(!ta_number)
01584         return add_item(list, max_age, desc, data);
01585       /* item desc and data are behind official struct */
01586       if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p) + list->info.desc_size + list->info.data_size)) )
01587         return(NULL);
01588       new_item_p->max_age = max_age;
01589       /* item desc is behind official struct */
01590       memcpy(&new_item_p[1],
01591              desc, list->info.desc_size);
01592       /* item data is behind official struct and desc */
01593       /* data might be empty! */
01594       if(data && list->info.data_size)
01595         memcpy(((__u8 *) new_item_p) + sizeof(*new_item_p) + list->info.desc_size,
01596                data,
01597                list->info.data_size);
01598 
01599       if(!list->ta_copied)
01600         { /* copy list to ta_list */
01601           if(ta_copy(ta_number, list))
01602             {
01603               rsbac_kfree(new_item_p);
01604               return NULL;
01605             }
01606         }
01607       else
01608         {
01609           if(list->ta_copied != ta_number)
01610             {
01611               rsbac_kfree(new_item_p);
01612               return NULL;
01613             }
01614         }
01615 
01616       if (!list->ta_head)
01617         {
01618           list->ta_head=new_item_p;
01619           list->ta_tail=new_item_p;
01620           list->ta_curr=new_item_p;
01621           list->ta_count = 1;
01622           new_item_p->prev=NULL;
01623           new_item_p->next=NULL;
01624           return new_item_p;
01625         }
01626       if(list->compare)
01627         return ta_insert_item_compare(list, desc, new_item_p);
01628       else
01629         return ta_insert_item_memcmp(list, desc, new_item_p);
01630     }
01631 #endif
01632 
01633 
01634 static struct rsbac_list_item_t * insert_lol_subitem_compare(
01635     struct rsbac_list_lol_reg_item_t * list,
01636     struct rsbac_list_lol_item_t * sublist,
01637     void * subdesc,
01638     struct rsbac_list_item_t * new_item_p)
01639     {
01640       struct rsbac_list_item_t * curr;
01641 
01642       curr = sublist->curr;
01643       if(!curr)
01644         curr = sublist->head;
01645       if((list->subcompare(subdesc, &curr[1]) > 0))
01646         {
01647           curr = curr->next;
01648           while (   curr
01649                  && (list->subcompare(subdesc, &curr[1]) > 0)
01650                 )
01651             curr = curr->next;
01652           if (curr)
01653             {
01654               /* insert before curr */
01655               new_item_p->prev=curr->prev;
01656               new_item_p->next=curr;
01657               curr->prev->next=new_item_p;
01658               curr->prev=new_item_p;
01659             }
01660           else
01661             {
01662               /* insert as last item */
01663               new_item_p->prev=sublist->tail;
01664               new_item_p->next=NULL;
01665               sublist->tail->next=new_item_p;
01666               sublist->tail=new_item_p;
01667             }
01668         }
01669       else
01670         {
01671           curr = curr->prev;
01672           while (   curr
01673                  && (list->subcompare(subdesc, &curr[1]) < 0)
01674                 )
01675             curr = curr->prev;
01676           if (curr)
01677             {
01678               /* insert after curr */
01679               new_item_p->prev=curr;
01680               new_item_p->next=curr->next;
01681               curr->next->prev=new_item_p;
01682               curr->next=new_item_p;
01683             }
01684           else
01685             {
01686               /* insert as first item */
01687               new_item_p->prev=NULL;
01688               new_item_p->next=sublist->head;
01689               sublist->head->prev=new_item_p;
01690               sublist->head=new_item_p;
01691             }
01692         }
01693       sublist->count++;
01694       sublist->curr=new_item_p;
01695       return new_item_p;
01696     }
01697 
01698 static struct rsbac_list_item_t * insert_lol_subitem_memcmp(
01699     struct rsbac_list_lol_reg_item_t * list,
01700     struct rsbac_list_lol_item_t * sublist,
01701     void * subdesc,
01702     struct rsbac_list_item_t * new_item_p)
01703     {
01704       struct rsbac_list_item_t * curr;
01705 
01706       curr = sublist->curr;
01707       if(!curr)
01708         curr = sublist->head;
01709       if(memcmp(subdesc,
01710                 &curr[1],
01711                 list->info.subdesc_size) > 0)
01712         {
01713           curr = curr->next;
01714           while (   curr
01715                  && (memcmp(subdesc,
01716                            &curr[1],
01717                            list->info.subdesc_size) > 0
01718                     )
01719                 )
01720             curr = curr->next;
01721           if (curr)
01722             {
01723               /* insert before curr */
01724               new_item_p->prev=curr->prev;
01725               new_item_p->next=curr;
01726               curr->prev->next=new_item_p;
01727               curr->prev=new_item_p;
01728             }
01729           else
01730             {
01731               /* insert as last item */
01732               new_item_p->prev=sublist->tail;
01733               new_item_p->next=NULL;
01734               sublist->tail->next=new_item_p;
01735               sublist->tail=new_item_p;
01736             }
01737         }
01738       else
01739         {
01740           curr = curr->prev;
01741           while (   curr
01742                  && (memcmp(subdesc,
01743                            &curr[1],
01744                            list->info.subdesc_size) < 0
01745                     )
01746                 )
01747             curr = curr->prev;
01748           if (curr)
01749             {
01750               /* insert after curr */
01751               new_item_p->prev=curr;
01752               new_item_p->next=curr->next;
01753               curr->next->prev=new_item_p;
01754               curr->next=new_item_p;
01755             }
01756           else
01757             {
01758               /* insert as first item */
01759               new_item_p->prev=NULL;
01760               new_item_p->next=sublist->head;
01761               sublist->head->prev=new_item_p;
01762               sublist->head=new_item_p;
01763             }
01764         }
01765       sublist->count++;
01766       sublist->curr=new_item_p;
01767       return new_item_p;
01768     }
01769 
01770 static struct rsbac_list_item_t * add_lol_subitem(
01771     struct rsbac_list_lol_reg_item_t * list,
01772     struct rsbac_list_lol_item_t     * sublist,
01773     rsbac_time_t max_age,
01774     void * subdesc,
01775     void * subdata)
01776     {
01777       struct rsbac_list_item_t * new_item_p = NULL;
01778 
01779       if(!list || !sublist || !subdesc)
01780         return NULL;
01781       if(list->info.subdata_size && !subdata)
01782         return NULL;
01783       /* item desc and data are behind official struct */
01784       if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p) + list->info.subdesc_size + list->info.subdata_size)) )
01785         return(NULL);
01786       new_item_p->max_age = max_age;
01787       /* item desc is behind official struct */
01788       memcpy(&new_item_p[1],
01789              subdesc,
01790              list->info.subdesc_size);
01791       /* item data is behind official struct and desc */
01792       /* subdata might be empty! */
01793       if(subdata && list->info.subdata_size)
01794         memcpy(((__u8 *) new_item_p) + sizeof(*new_item_p) + list->info.subdesc_size,
01795                subdata,
01796                list->info.subdata_size);
01797 
01798       /* Sublist was empty */
01799       if (!sublist->head)
01800         {
01801           sublist->head=new_item_p;
01802           sublist->tail=new_item_p;
01803           sublist->curr=new_item_p;
01804           sublist->count = 1;
01805           new_item_p->prev=NULL;
01806           new_item_p->next=NULL;          
01807           return(new_item_p);
01808         }  
01809       if(list->subcompare)
01810         return insert_lol_subitem_compare(list, sublist, subdesc, new_item_p);
01811       else
01812         return insert_lol_subitem_memcmp(list, sublist, subdesc, new_item_p);
01813     }
01814 
01815 static struct rsbac_list_lol_item_t * insert_lol_item_compare(
01816     struct rsbac_list_lol_reg_item_t * list,
01817     void * desc,
01818     struct rsbac_list_lol_item_t * new_item_p)
01819     {
01820       struct rsbac_list_lol_item_t * curr;
01821 
01822       curr = list->curr;
01823       if(!curr)
01824         curr = list->head;
01825       if((list->compare(desc, &curr[1]) > 0))
01826         {
01827           curr = curr->next;
01828           while (   curr
01829                  && (list->compare(desc, &curr[1]) > 0)
01830                 )
01831             curr = curr->next;
01832           if (curr)
01833             {
01834               /* insert before curr */
01835               new_item_p->prev=curr->prev;
01836               new_item_p->next=curr;
01837               curr->prev->next=new_item_p;
01838               curr->prev=new_item_p;
01839             }
01840           else
01841             {
01842               /* insert as last item */
01843               new_item_p->prev=list->tail;
01844               new_item_p->next=NULL;
01845               list->tail->next=new_item_p;
01846               list->tail=new_item_p;
01847             }
01848         }
01849       else
01850         {
01851           curr = curr->prev;
01852           while (   curr
01853                  && (list->compare(desc, &curr[1]) < 0)
01854                 )
01855             curr = curr->prev;
01856           if (curr)
01857             {
01858               /* insert after curr */
01859               new_item_p->prev=curr;
01860               new_item_p->next=curr->next;
01861               curr->next->prev=new_item_p;
01862               curr->next=new_item_p;
01863             }
01864           else
01865             {
01866               /* insert as first item */
01867               new_item_p->prev=NULL;
01868               new_item_p->next=list->head;
01869               list->head->prev=new_item_p;
01870               list->head=new_item_p;
01871             }
01872         }
01873       list->count++;
01874       list->curr=new_item_p;
01875       return new_item_p;
01876     }
01877 
01878 static struct rsbac_list_lol_item_t * insert_lol_item_memcmp(
01879     struct rsbac_list_lol_reg_item_t * list,
01880     void * desc,
01881     struct rsbac_list_lol_item_t * new_item_p)
01882     {
01883       struct rsbac_list_lol_item_t * curr;
01884 
01885       curr = list->curr;
01886       if(!curr)
01887         curr = list->head;
01888       if(memcmp(desc,
01889                 &curr[1],
01890                 list->info.desc_size) > 0)
01891         {
01892           curr = curr->next;
01893           while (   curr
01894                  && (memcmp(desc,
01895                            &curr[1],
01896                            list->info.desc_size) > 0
01897                     )
01898                 )
01899             curr = curr->next;
01900           if (curr)
01901             {
01902               /* insert before curr */
01903               new_item_p->prev=curr->prev;
01904               new_item_p->next=curr;
01905               curr->prev->next=new_item_p;
01906               curr->prev=new_item_p;
01907             }
01908           else
01909             {
01910               /* insert as last item */
01911               new_item_p->prev=list->tail;
01912               new_item_p->next=NULL;
01913               list->tail->next=new_item_p;
01914               list->tail=new_item_p;
01915             }
01916         }
01917       else
01918         {
01919           curr = curr->prev;
01920           while (   curr
01921                  && (memcmp(desc,
01922                            &curr[1],
01923                            list->info.desc_size) < 0
01924                     )
01925                 )
01926             curr = curr->prev;
01927           if (curr)
01928             {
01929               /* insert after curr */
01930               new_item_p->prev=curr;
01931               new_item_p->next=curr->next;
01932               curr->next->prev=new_item_p;
01933               curr->next=new_item_p;
01934             }
01935           else
01936             {
01937               /* insert as first item */
01938               new_item_p->prev=NULL;
01939               new_item_p->next=list->head;
01940               list->head->prev=new_item_p;
01941               list->head=new_item_p;
01942             }
01943         }
01944       list->count++;
01945       list->curr=new_item_p;
01946       return new_item_p;
01947     }
01948 
01949 static struct rsbac_list_lol_item_t * add_lol_item(
01950     struct rsbac_list_lol_reg_item_t * list,
01951     rsbac_time_t max_age,
01952     void * desc,
01953     void * data)
01954     {
01955       struct rsbac_list_lol_item_t * new_item_p = NULL;
01956 
01957       if(!list || !desc)
01958         return NULL;
01959       if(list->info.data_size && !data)
01960         return NULL;
01961       /* item desc and data are behind official struct */
01962       if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p) + list->info.desc_size + list->info.data_size)) )
01963         return(NULL);
01964       /* Init sublist */
01965       new_item_p->head = NULL;
01966       new_item_p->tail = NULL;
01967       new_item_p->curr = NULL;
01968       new_item_p->count = 0;
01969       new_item_p->max_age = max_age;
01970       /* item desc is behind official struct */
01971       memcpy(&new_item_p[1],
01972              desc,
01973              list->info.desc_size);
01974       /* item data is behind official struct and desc */
01975       /* data might be empty! */
01976       if(data && list->info.data_size)
01977         memcpy(((__u8 *) new_item_p) + sizeof(*new_item_p) + list->info.desc_size,
01978                data,
01979                list->info.data_size);
01980 
01981       if (!list->head)
01982         {
01983           list->head=new_item_p;
01984           list->tail=new_item_p;
01985           list->curr=new_item_p;
01986           list->count = 1;
01987           new_item_p->prev=NULL;
01988           new_item_p->next=NULL;          
01989           return(new_item_p);
01990         }
01991       if(list->compare)
01992         return insert_lol_item_compare(list, desc, new_item_p);
01993       else
01994         return insert_lol_item_memcmp(list, desc, new_item_p);
01995     }
01996 
01997 #ifdef CONFIG_RSBAC_LIST_TRANS
01998 static struct rsbac_list_lol_item_t * ta_insert_lol_item_compare(
01999     struct rsbac_list_lol_reg_item_t * list,
02000     void * desc,
02001     struct rsbac_list_lol_item_t * new_item_p)
02002     {
02003       struct rsbac_list_lol_item_t * curr;
02004 
02005       curr = list->ta_curr;
02006       if(!curr)
02007         curr = list->ta_head;
02008       if((list->compare(desc, &curr[1]) > 0))
02009         {
02010           curr = curr->next;
02011           while (   curr
02012                  && (list->compare(desc, &curr[1]) > 0)
02013                 )
02014             curr = curr->next;
02015           if (curr)
02016             {
02017               /* insert before curr */
02018               new_item_p->prev=curr->prev;
02019               new_item_p->next=curr;
02020               curr->prev->next=new_item_p;
02021               curr->prev=new_item_p;
02022             }
02023           else
02024             {
02025               /* insert as last item */
02026               new_item_p->prev=list->ta_tail;
02027               new_item_p->next=NULL;
02028               list->ta_tail->next=new_item_p;
02029               list->ta_tail=new_item_p;
02030             }
02031         }
02032       else
02033         {
02034           curr = curr->prev;
02035           while (   curr
02036                  && (list->compare(desc, &curr[1]) < 0)
02037                 )
02038             curr = curr->prev;
02039           if (curr)
02040             {
02041               /* insert after curr */
02042               new_item_p->prev=curr;
02043               new_item_p->next=curr->next;
02044               curr->next->prev=new_item_p;
02045               curr->next=new_item_p;
02046             }
02047           else
02048             {
02049               /* insert as first item */
02050               new_item_p->prev=NULL;
02051               new_item_p->next=list->ta_head;
02052               list->ta_head->prev=new_item_p;
02053               list->ta_head=new_item_p;
02054             }
02055         }
02056       list->ta_count++;
02057       list->ta_curr=new_item_p;
02058       return new_item_p;
02059     }
02060 
02061 static struct rsbac_list_lol_item_t * ta_insert_lol_item_memcmp(
02062     struct rsbac_list_lol_reg_item_t * list,
02063     void * desc,
02064     struct rsbac_list_lol_item_t * new_item_p)
02065     {
02066       struct rsbac_list_lol_item_t * curr;
02067 
02068       curr = list->ta_curr;
02069       if(!curr)
02070         curr = list->ta_head;
02071       if(memcmp(desc,
02072                 &curr[1],
02073                 list->info.desc_size) > 0)
02074         {
02075           curr = curr->next;
02076           while (   curr
02077                  && (memcmp(desc,
02078                            &curr[1],
02079                            list->info.desc_size) > 0
02080                     )
02081                 )
02082             curr = curr->next;
02083           if (curr)
02084             {
02085               /* insert before curr */
02086               new_item_p->prev=curr->prev;
02087               new_item_p->next=curr;
02088               curr->prev->next=new_item_p;
02089               curr->prev=new_item_p;
02090             }
02091           else
02092             {
02093               /* insert as last item */
02094               new_item_p->prev=list->ta_tail;
02095               new_item_p->next=NULL;
02096               list->ta_tail->next=new_item_p;
02097               list->ta_tail=new_item_p;
02098             }
02099         }
02100       else
02101         {
02102           curr = curr->prev;
02103           while (   curr
02104                  && (memcmp(desc,
02105                            &curr[1],
02106                            list->info.desc_size) < 0
02107                     )
02108                 )
02109             curr = curr->prev;
02110           if (curr)
02111             {
02112               /* insert after curr */
02113               new_item_p->prev=curr;
02114               new_item_p->next=curr->next;
02115               curr->next->prev=new_item_p;
02116               curr->next=new_item_p;
02117             }
02118           else
02119             {
02120               /* insert as first item */
02121               new_item_p->prev=NULL;
02122               new_item_p->next=list->ta_head;
02123               list->ta_head->prev=new_item_p;
02124               list->ta_head=new_item_p;
02125             }
02126         }
02127       list->ta_count++;
02128       list->ta_curr=new_item_p;
02129       return new_item_p;
02130     }
02131 
02132 static struct rsbac_list_lol_item_t * ta_add_lol_item(
02133     rsbac_list_ta_number_t ta_number,
02134     struct rsbac_list_lol_reg_item_t * list,
02135     rsbac_time_t max_age,
02136     void * desc,
02137     void * data)
02138     {
02139       struct rsbac_list_lol_item_t * new_item_p = NULL;
02140 
02141       if(!list || !desc)
02142         return NULL;
02143       if(list->info.data_size && !data)
02144         return NULL;
02145       if(!ta_number)
02146         return add_lol_item(list, max_age, desc, data);
02147       /* item desc and data are behind official struct */
02148       if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p) + list->info.desc_size + list->info.data_size)) )
02149         return(NULL);
02150       /* Init sublist */
02151       new_item_p->head = NULL;
02152       new_item_p->tail = NULL;
02153       new_item_p->curr = NULL;
02154       new_item_p->count = 0;
02155       new_item_p->max_age = max_age;
02156       new_item_p->prev=NULL;
02157       new_item_p->next=NULL;          
02158       /* item desc is behind official struct */
02159       memcpy(&new_item_p[1],
02160              desc,
02161              list->info.desc_size);
02162       /* item data is behind official struct and desc */
02163       /* data might be empty! */
02164       if(data && list->info.data_size)
02165         memcpy(((__u8 *) new_item_p) + sizeof(*new_item_p) + list->info.desc_size,
02166                data,
02167                list->info.data_size);
02168 
02169       if(!list->ta_copied)
02170         { /* copy list to ta_list */
02171           if(ta_lol_copy(ta_number, list))
02172             {
02173               rsbac_kfree(new_item_p);
02174               return NULL;
02175             }
02176         }
02177       else
02178         {
02179           if(list->ta_copied != ta_number)
02180             {
02181               rsbac_kfree(new_item_p);
02182               return NULL;
02183             }
02184         }
02185 
02186       if (!list->ta_head)
02187         {
02188           list->ta_head=new_item_p;
02189           list->ta_tail=new_item_p;
02190           list->ta_curr=new_item_p;
02191           list->ta_count = 1;
02192           return(new_item_p);
02193         }
02194       if(list->compare)
02195         return ta_insert_lol_item_compare(list, desc, new_item_p);
02196       else
02197         return ta_insert_lol_item_memcmp(list, desc, new_item_p);
02198     }
02199 #endif
02200 
02201 /* Add registration items */
02202 
02203 /* no locking needed */
02204 static inline struct rsbac_list_reg_item_t* 
02205          create_reg(struct rsbac_list_info_t             * info_p,
02206                            u_int                         flags,
02207                            rsbac_list_compare_function_t * compare,
02208                            rsbac_list_get_conv_t       * get_conv,
02209                            void                        * def_data,
02210                            char                        * name,
02211                            kdev_t                        device)
02212     {
02213       struct rsbac_list_reg_item_t * new_item_p = NULL;
02214 
02215       if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p))) )
02216         return(NULL);
02217       new_item_p->info = *info_p;
02218       if(!def_data)
02219         flags &= ~RSBAC_LIST_DEF_DATA;
02220       new_item_p->flags = flags;
02221       new_item_p->compare = compare;
02222       new_item_p->get_conv = get_conv;
02223       if(flags & RSBAC_LIST_DEF_DATA)
02224         {
02225           new_item_p->def_data = rsbac_kmalloc(info_p->data_size);
02226           if(new_item_p->def_data)
02227             memcpy(new_item_p->def_data, def_data, info_p->data_size);
02228           else
02229             {
02230               rsbac_kfree(new_item_p);
02231               return NULL;
02232             }
02233         }
02234       else
02235         new_item_p->def_data = NULL;
02236       if(name)
02237         {
02238           strncpy(new_item_p->name, name, RSBAC_LIST_MAX_FILENAME);
02239           new_item_p->name[RSBAC_LIST_MAX_FILENAME] = 0;
02240         }
02241       else
02242         {
02243           strcpy(new_item_p->name, RSBAC_LIST_NONAME);
02244         }
02245       new_item_p->device = device;
02246       new_item_p->head   = NULL;
02247       new_item_p->tail   = NULL;
02248       new_item_p->curr   = NULL;
02249       new_item_p->lock   = RW_LOCK_UNLOCKED;
02250       new_item_p->count  = 0;
02251       new_item_p->dirty  = FALSE;
02252       if(flags & RSBAC_LIST_NO_WRITE)
02253         new_item_p->no_write = TRUE;
02254       else
02255         new_item_p->no_write = FALSE;
02256       new_item_p->lastchange.sec = 0;
02257       new_item_p->lastchange.nsec = 0;
02258 #ifdef CONFIG_RSBAC_LIST_TRANS
02259       new_item_p->ta_copied = FALSE;
02260       new_item_p->ta_head   = NULL;
02261       new_item_p->ta_tail   = NULL;
02262       new_item_p->ta_curr   = NULL;
02263       new_item_p->ta_count  = 0;
02264 #endif
02265       new_item_p->self = new_item_p;
02266       return new_item_p;
02267     }
02268 
02269 /* locking needed */
02270 static struct rsbac_list_reg_item_t* 
02271          add_reg(struct rsbac_list_reg_item_t* new_item_p)
02272     {
02273       if (!reg_head.head)
02274         {
02275           reg_head.head=new_item_p;
02276           reg_head.tail=new_item_p;
02277           reg_head.curr=new_item_p;
02278           reg_head.count = 1;
02279           new_item_p->prev=NULL;
02280           new_item_p->next=NULL;          
02281         }  
02282       else
02283         {
02284           new_item_p->prev=reg_head.tail;
02285           new_item_p->next=NULL;
02286           reg_head.tail->next=new_item_p;
02287           reg_head.tail=new_item_p;
02288           reg_head.curr=new_item_p;
02289           reg_head.count++;
02290         };
02291       return(new_item_p);
02292     }
02293 
02294 /* no locking needed */
02295 static inline struct rsbac_list_lol_reg_item_t* 
02296      create_lol_reg(struct rsbac_list_lol_info_t       * info_p,
02297                            u_int                         flags,
02298                            rsbac_list_compare_function_t * compare,
02299                            rsbac_list_compare_function_t * subcompare,
02300                            rsbac_list_get_conv_t       * get_conv,
02301                            rsbac_list_get_conv_t       * get_subconv,
02302                            void                        * def_data,
02303                            void                        * def_subdata,
02304                            char                        * name,
02305                            kdev_t                        device)
02306     {
02307       struct rsbac_list_lol_reg_item_t * new_item_p = NULL;
02308 
02309       if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p))) )
02310         return(NULL);
02311       new_item_p->info = *info_p;
02312       if(info_p->data_size && !def_data)
02313         flags &= ~RSBAC_LIST_DEF_DATA;
02314       if(!def_subdata)
02315         flags &= ~RSBAC_LIST_DEF_SUBDATA;
02316       new_item_p->flags = flags;
02317       new_item_p->compare = compare;
02318       new_item_p->subcompare = subcompare;
02319       new_item_p->get_conv = get_conv;
02320       new_item_p->get_subconv = get_subconv;
02321       if(   (flags & RSBAC_LIST_DEF_DATA)
02322          && (info_p->data_size)
02323         )
02324         {
02325           new_item_p->def_data = rsbac_kmalloc(info_p->data_size);
02326           if(new_item_p->def_data)
02327             memcpy(new_item_p->def_data, def_data, info_p->data_size);
02328           else
02329             {
02330               rsbac_kfree(new_item_p);
02331               return NULL;
02332             }
02333         }
02334       else
02335         new_item_p->def_data = NULL;
02336       if(flags & RSBAC_LIST_DEF_SUBDATA)
02337         {
02338           new_item_p->def_subdata = rsbac_kmalloc(info_p->subdata_size);
02339           if(new_item_p->def_subdata)
02340             memcpy(new_item_p->def_subdata, def_subdata, info_p->subdata_size);
02341           else
02342             {
02343               if(new_item_p->def_data)
02344                 rsbac_kfree(new_item_p->def_data);
02345               rsbac_kfree(new_item_p);
02346               return NULL;
02347             }
02348         }
02349       else
02350         new_item_p->def_subdata = NULL;
02351       if(name)
02352         {
02353           strncpy(new_item_p->name, name, RSBAC_LIST_MAX_FILENAME);
02354           new_item_p->name[RSBAC_LIST_MAX_FILENAME] = 0;
02355         }
02356       else
02357         {
02358           strcpy(new_item_p->name, RSBAC_LIST_NONAME);
02359         }
02360       new_item_p->device = device;
02361       new_item_p->head   = NULL;
02362       new_item_p->tail   = NULL;
02363       new_item_p->curr   = NULL;
02364       new_item_p->lock   = RW_LOCK_UNLOCKED;
02365       new_item_p->count  = 0;
02366       new_item_p->dirty  = FALSE;
02367       if(flags & RSBAC_LIST_NO_WRITE)
02368         new_item_p->no_write = TRUE;
02369       else
02370         new_item_p->no_write = FALSE;
02371       new_item_p->lastchange.sec = 0;
02372       new_item_p->lastchange.nsec = 0;
02373 #ifdef CONFIG_RSBAC_LIST_TRANS
02374       new_item_p->ta_copied = FALSE;
02375       new_item_p->ta_head   = NULL;
02376       new_item_p->ta_tail   = NULL;
02377       new_item_p->ta_curr   = NULL;
02378       new_item_p->ta_count  = 0;
02379 #endif
02380       new_item_p->self = new_item_p;
02381       return(new_item_p);
02382     }
02383 
02384 /* locking needed */
02385 static struct rsbac_list_lol_reg_item_t* 
02386      add_lol_reg(struct rsbac_list_lol_reg_item_t * new_item_p)
02387     {
02388       if (!lol_reg_head.head)
02389         {
02390           lol_reg_head.head=new_item_p;
02391           lol_reg_head.tail=new_item_p;
02392           lol_reg_head.curr=new_item_p;
02393           lol_reg_head.count = 1;
02394           new_item_p->prev=NULL;
02395           new_item_p->next=NULL;          
02396         }  
02397       else
02398         {
02399           new_item_p->prev=lol_reg_head.tail;
02400           new_item_p->next=NULL;
02401           lol_reg_head.tail->next=new_item_p;
02402           lol_reg_head.tail=new_item_p;
02403           lol_reg_head.curr=new_item_p;
02404           lol_reg_head.count++;
02405         };
02406       return(new_item_p);
02407     }
02408 
02409 /* Removing items */
02410 
02411 static void do_remove_item(
02412     struct rsbac_list_reg_item_t * list,
02413     struct rsbac_list_item_t * item_p)
02414   {
02415     if(!list || !item_p)
02416       return;
02417 
02418     if ( (list->head == item_p) )
02419        { /* item is head */
02420          if ( (list->tail == item_p) )
02421            { /* item is head and tail = only item -> list will be empty*/
02422              list->head = NULL;
02423              list->tail = NULL;
02424            }
02425          else
02426            { /* item is head, but not tail -> next item becomes head */
02427              item_p->next->prev = NULL;
02428              list->head = item_p->next;
02429            };
02430        }
02431     else
02432        { /* item is not head */
02433          if ( (list->tail == item_p) )
02434            { /*item is not head, but tail -> previous item becomes tail*/
02435              item_p->prev->next = NULL;
02436              list->tail = item_p->prev;
02437            }
02438          else
02439            { /* item is neither head nor tail -> item is cut out */
02440              item_p->prev->next = item_p->next;
02441              item_p->next->prev = item_p->prev;
02442            }
02443        }
02444     /* curr is no longer valid -> reset */
02445     list->curr=NULL;
02446     /* adjust counter */
02447     list->count--;
02448     /* now we can remove the item from memory */
02449     rsbac_kfree(item_p);    
02450   } /* end of do_remove_item() */
02451 
02452 static void remove_item(
02453     struct rsbac_list_reg_item_t * list,
02454     void * desc)
02455   {
02456     struct rsbac_list_item_t * item_p;
02457 
02458     if(!list || !desc)
02459       return;
02460     /* first we must locate the item. */
02461     if ( (item_p = lookup_item(list, desc)) )
02462       {
02463         do_remove_item(list, item_p);
02464       }
02465   }
02466 
02467 static void remove_all_items(struct rsbac_list_reg_item_t * list)
02468     {
02469       struct rsbac_list_item_t     * item_p;
02470       struct rsbac_list_item_t     * next_item_p;
02471 
02472       /* cleanup all items */
02473       item_p = list->head;
02474       while(item_p)
02475         {
02476           next_item_p = item_p->next;
02477           rsbac_kfree(item_p);
02478           item_p = next_item_p;
02479         }
02480       list->head = NULL;
02481       list->tail = NULL;
02482       list->curr = NULL;
02483       list->count = 0;
02484     }
02485 
02486 #ifdef CONFIG_RSBAC_LIST_TRANS
02487 static void ta_do_remove_item(
02488     struct rsbac_list_reg_item_t * list,
02489     struct rsbac_list_item_t * item_p)
02490   {
02491     if(!list || !item_p)
02492       return;
02493 
02494     if ( (list->ta_head == item_p) )
02495        { /* item is head */
02496          if ( (list->ta_tail == item_p) )
02497            { /* item is head and tail = only item -> list will be empty*/
02498              list->ta_head = NULL;
02499              list->ta_tail = NULL;
02500            }
02501          else
02502            { /* item is head, but not tail -> next item becomes head */
02503              item_p->next->prev = NULL;
02504              list->ta_head = item_p->next;
02505            }
02506        }
02507     else
02508        { /* item is not head */
02509          if ( (list->ta_tail == item_p) )
02510            { /*item is not head, but tail -> previous item becomes tail*/
02511              item_p->prev->next = NULL;
02512              list->ta_tail = item_p->prev;
02513            }
02514          else
02515            { /* item is neither head nor tail -> item is cut out */
02516              item_p->prev->next = item_p->next;
02517              item_p->next->prev = item_p->prev;
02518            }
02519        }
02520     /* curr is no longer valid -> reset */
02521     list->ta_curr=NULL;
02522     /* adjust counter */
02523     list->ta_count--;
02524     /* now we can remove the item from memory */
02525     rsbac_kfree(item_p);    
02526   }
02527 
02528 static void ta_remove_item(
02529     rsbac_list_ta_number_t ta_number,
02530     struct rsbac_list_reg_item_t * list,
02531     void * desc)
02532   {
02533     struct rsbac_list_item_t * item_p;
02534 
02535     if(!list || !desc)
02536       return;
02537     if(!ta_number)
02538       return remove_item(list, desc);
02539     /* first we must locate the item. */
02540     if ( (item_p = ta_lookup_item(ta_number, list, desc)) )
02541       {
02542         ta_do_remove_item(list, item_p);
02543       }
02544   }
02545 
02546 static void ta_remove_all_items(struct rsbac_list_reg_item_t * list)
02547     {
02548       struct rsbac_list_item_t     * item_p;
02549       struct rsbac_list_item_t     * next_item_p;
02550 
02551       /* cleanup all items */
02552       item_p = list->ta_head;
02553       while(item_p)
02554         {
02555           next_item_p = item_p->next;
02556           rsbac_kfree(item_p);
02557           item_p = next_item_p;
02558         }
02559       list->ta_head = NULL;
02560       list->ta_tail = NULL;
02561       list->ta_curr = NULL;
02562       list->ta_count = 0;
02563     }
02564 #endif
02565 
02566 static void do_remove_lol_subitem(
02567     struct rsbac_list_lol_item_t * sublist,
02568     struct rsbac_list_item_t     * item_p)
02569   {
02570     if(!sublist || !item_p)
02571       return;
02572 
02573     if ( (sublist->head == item_p) )
02574       { /* item is head */
02575         if ( (sublist->tail == item_p) )
02576           { /* item is head and tail = only item -> list will be empty*/
02577             sublist->head = NULL;
02578             sublist->tail = NULL;
02579           }
02580         else
02581           { /* item is head, but not tail -> next item becomes head */
02582             item_p->next->prev = NULL;
02583             sublist->head = item_p->next;
02584           }
02585       }
02586     else
02587       { /* item is not head */
02588         if ( (sublist->tail == item_p) )
02589           { /*item is not head, but tail -> previous item becomes tail*/
02590             item_p->prev->next = NULL;
02591             sublist->tail = item_p->prev;
02592           }
02593         else
02594           { /* item is neither head nor tail -> item is cut out */
02595             item_p->prev->next = item_p->next;
02596             item_p->next->prev = item_p->prev;
02597           }
02598       }
02599     /* curr is no longer valid -> reset */
02600     sublist->curr=NULL;
02601     /* adjust counter */
02602     sublist->count--;
02603     /* now we can remove the item from memory */
02604     rsbac_kfree(item_p);    
02605   }
02606 
02607 static void remove_lol_subitem(
02608     struct rsbac_list_lol_reg_item_t * list,
02609     struct rsbac_list_lol_item_t     * sublist,
02610     void * subdesc)
02611   {
02612     struct rsbac_list_item_t     * item_p;
02613 
02614     if(!list || !sublist || !subdesc)
02615       return;
02616 
02617     /* first we must locate the item. */
02618     if ( (item_p = lookup_lol_subitem(list, sublist, subdesc)) )
02619       {
02620         do_remove_lol_subitem(sublist, item_p);
02621       }
02622   }
02623 
02624 
02625 static void do_remove_lol_item(
02626     struct rsbac_list_lol_reg_item_t * list,
02627     struct rsbac_list_lol_item_t * item_p)
02628   {
02629     struct rsbac_list_item_t     * subitem_p;
02630     struct rsbac_list_item_t     * next_subitem_p;
02631 
02632     if(!list || !item_p)
02633       return;
02634 
02635     if ( (list->head == item_p) )
02636        { /* item is head */
02637          if ( (list->tail == item_p) )
02638            { /* item is head and tail = only item -> list will be empty*/
02639              list->head = NULL;
02640              list->tail = NULL;
02641            }
02642          else
02643            { /* item is head, but not tail -> next item becomes head */
02644 #ifdef CONFIG_RSBAC_DEBUG
02645              if(!item_p->next)
02646                { /* list corrupted! */
02647                  rsbac_printk(KERN_WARNING
02648                         "do_remove_lol_item(): list %s corrupted: invalid next!\n",
02649                         list->name);
02650                }
02651              else
02652 #endif
02653                {
02654                  item_p->next->prev = NULL;
02655                  list->head = item_p->next;
02656                }
02657            }
02658        }
02659     else
02660        { /* item is not head */
02661          if ( (list->tail == item_p) )
02662            { /*item is not head, but tail -> previous item becomes tail*/
02663 #ifdef CONFIG_RSBAC_DEBUG
02664              if(!item_p->prev)
02665                { /* list corrupted! */
02666                  rsbac_printk(KERN_WARNING
02667                         "do_remove_lol_item(): list %s corrupted: invalid prev!\n",
02668                         list->name);
02669                }
02670              else
02671 #endif
02672                {
02673                  item_p->prev->next = NULL;
02674                  list->tail = item_p->prev;
02675                }
02676            }
02677          else
02678            { /* item is neither head nor tail -> item is cut out */
02679 #ifdef CONFIG_RSBAC_DEBUG
02680              if(!item_p->prev)
02681                { /* list corrupted! */
02682                  rsbac_printk(KERN_WARNING
02683                         "do_remove_lol_item(): list %s corrupted: invalid prev!\n",
02684                         list->name);
02685                }
02686              else
02687              if(!item_p->next)
02688                { /* list corrupted! */
02689                  rsbac_printk(KERN_WARNING
02690                         "do_remove_lol_item(): list %s corrupted: invalid next!\n",
02691                         list->name);
02692                }
02693              else
02694 #endif
02695                {
02696                  item_p->prev->next = item_p->next;
02697                  item_p->next->prev = item_p->prev;
02698                }
02699            }
02700        }
02701     /* curr is no longer valid -> reset */
02702     list->curr=NULL;
02703     /* adjust counter */
02704     list->count--;
02705     /* first remove subitems */
02706     subitem_p = item_p->head;
02707     while(subitem_p)
02708       {
02709         next_subitem_p = subitem_p->next;
02710         rsbac_kfree(subitem_p);
02711         subitem_p = next_subitem_p;
02712       }
02713     /* now we can remove the item from memory */
02714     rsbac_kfree(item_p);    
02715   }
02716 
02717 static void remove_lol_item(
02718     struct rsbac_list_lol_reg_item_t * list,
02719     void * desc)
02720   {
02721     struct rsbac_list_lol_item_t * item_p;
02722 
02723     if(!list || !desc)
02724       return;
02725 
02726     /* first we must locate the item. */
02727     if ( (item_p = lookup_lol_item(list, desc)) )
02728       {
02729         do_remove_lol_item(list, item_p);
02730       }
02731   }
02732 
02733 #ifdef CONFIG_RSBAC_LIST_TRANS
02734 static void ta_do_remove_lol_item(
02735     struct rsbac_list_lol_reg_item_t * list,
02736     struct rsbac_list_lol_item_t * item_p)
02737   {
02738     struct rsbac_list_item_t     * subitem_p;
02739     struct rsbac_list_item_t     * next_subitem_p;
02740 
02741     if(!list || !item_p)
02742       return;
02743 
02744     if ( (list->ta_head == item_p) )
02745        { /* item is head */
02746          if ( (list->ta_tail == item_p) )
02747            { /* item is head and tail = only item -> list will be empty*/
02748              list->ta_head = NULL;
02749              list->ta_tail = NULL;
02750            }
02751          else
02752            { /* item is head, but not tail -> next item becomes head */
02753 #ifdef CONFIG_RSBAC_DEBUG
02754              if(!item_p->next)
02755                { /* list corrupted! */
02756                  rsbac_printk(KERN_WARNING
02757                         "do_remove_lol_item(): list %s corrupted: invalid next!\n",
02758                         list->name);
02759                }
02760              else
02761 #endif
02762                {
02763                  item_p->next->prev = NULL;
02764                  list->ta_head = item_p->next;
02765                }
02766            }
02767        }
02768     else
02769        { /* item is not head */
02770          if ( (list->ta_tail == item_p) )
02771            { /*item is not head, but tail -> previous item becomes tail*/
02772 #ifdef CONFIG_RSBAC_DEBUG
02773              if(!item_p->prev)
02774                { /* list corrupted! */
02775                  rsbac_printk(KERN_WARNING
02776                         "do_remove_lol_item(): list %s corrupted: invalid prev!\n",
02777                         list->name);
02778                }
02779              else
02780 #endif
02781                {
02782                  item_p->prev->next = NULL;
02783                  list->ta_tail = item_p->prev;
02784                }
02785            }
02786          else
02787            { /* item is neither head nor tail -> item is cut out */
02788 #ifdef CONFIG_RSBAC_DEBUG
02789              if(!item_p->prev)
02790                { /* list corrupted! */
02791                  rsbac_printk(KERN_WARNING
02792                         "do_remove_lol_item(): list %s corrupted: invalid prev!\n",
02793                         list->name);
02794                }
02795              else
02796              if(!item_p->next)
02797                { /* list corrupted! */
02798                  rsbac_printk(KERN_WARNING
02799                         "do_remove_lol_item(): list %s corrupted: invalid next!\n",
02800                         list->name);
02801                }
02802              else
02803 #endif
02804                {
02805                  item_p->prev->next = item_p->next;
02806                  item_p->next->prev = item_p->prev;
02807                }
02808            }
02809        }
02810     /* curr is no longer valid -> reset */
02811     list->ta_curr=NULL;
02812     /* adjust counter */
02813     list->ta_count--;
02814 
02815     /* remove subitems */
02816     subitem_p = item_p->head;
02817     while(subitem_p)
02818       {
02819         next_subitem_p = subitem_p->next;
02820         rsbac_kfree(subitem_p);
02821         subitem_p = next_subitem_p;
02822       }
02823     /* now we can remove the item from memory */
02824     rsbac_kfree(item_p);    
02825   }
02826 
02827 static void ta_remove_lol_item(
02828     rsbac_list_ta_number_t ta_number,
02829     struct rsbac_list_lol_reg_item_t * list,
02830     void * desc)
02831   {
02832     struct rsbac_list_lol_item_t * item_p;
02833 
02834     if(!list || !desc)
02835       return;
02836 
02837     /* first we must locate the item. */
02838     if ( (item_p = ta_lookup_lol_item(ta_number, list, desc)) )
02839       {
02840         ta_do_remove_lol_item(list, item_p);
02841       }
02842   }
02843 #endif
02844 
02845 static void remove_all_lol_subitems(
02846     struct rsbac_list_lol_item_t     * sublist)
02847     {
02848       struct rsbac_list_item_t     * subitem_p;
02849       struct rsbac_list_item_t     * next_subitem_p;
02850 
02851       /* cleanup all items */
02852       subitem_p = sublist->head;
02853       while(subitem_p)
02854         {
02855           next_subitem_p = subitem_p->next;
02856           rsbac_kfree(subitem_p);
02857           subitem_p = next_subitem_p;
02858         }
02859       sublist->head = NULL;
02860       sublist->tail = NULL;
02861       sublist->curr = NULL;
02862       sublist->count = 0;
02863     }
02864 
02865 static void remove_all_lol_items(struct rsbac_list_lol_reg_item_t * list)
02866     {
02867       struct rsbac_list_lol_item_t * item_p;
02868       struct rsbac_list_lol_item_t * next_item_p;
02869       struct rsbac_list_item_t     * subitem_p;
02870       struct rsbac_list_item_t     * next_subitem_p;
02871 
02872       /* cleanup all items */
02873       item_p = list->head;
02874       while(item_p)
02875         {
02876           /* first remove subitems */
02877           subitem_p = item_p->head;
02878           while(subitem_p)
02879             {
02880               next_subitem_p = subitem_p->next;
02881               rsbac_kfree(subitem_p);
02882               subitem_p = next_subitem_p;
02883             }
02884           next_item_p = item_p->next;
02885           rsbac_kfree(item_p);
02886           item_p = next_item_p;
02887         }
02888       list->head = NULL;
02889       list->tail = NULL;
02890       list->curr = NULL;
02891       list->count = 0;
02892     }
02893 
02894 #ifdef CONFIG_RSBAC_LIST_TRANS
02895 static void ta_remove_all_lol_items(struct rsbac_list_lol_reg_item_t * list)
02896     {
02897       struct rsbac_list_lol_item_t * item_p;
02898       struct rsbac_list_lol_item_t * next_item_p;
02899       struct rsbac_list_item_t     * subitem_p;
02900       struct rsbac_list_item_t     * next_subitem_p;
02901 
02902       /* cleanup all items */
02903       item_p = list->ta_head;
02904       while(item_p)
02905         {
02906           /* first remove subitems */
02907           subitem_p = item_p->head;
02908           while(subitem_p)
02909             {
02910               next_subitem_p = subitem_p->next;
02911               rsbac_kfree(subitem_p);
02912               subitem_p = next_subitem_p;
02913             }
02914           next_item_p = item_p->next;
02915           rsbac_kfree(item_p);
02916           item_p = next_item_p;
02917         }
02918       list->ta_head = NULL;
02919       list->ta_tail = NULL;
02920       list->ta_curr = NULL;
02921       list->ta_count = 0;
02922     }
02923 #endif
02924 
02925 /* Remove registration items */
02926 
02927 /* no locking needed */
02928 static void clear_reg(struct rsbac_list_reg_item_t * item_p)
02929     {
02930       if(item_p)
02931         {
02932           /* now we can remove the item from memory */
02933           remove_all_items(item_p);
02934           if(item_p->def_data)
02935             rsbac_kfree(item_p->def_data);
02936           rsbac_kfree(item_p);
02937         }
02938     }
02939 
02940 /* locking needed */
02941 static void remove_reg(struct rsbac_list_reg_item_t *  handle)
02942     {
02943       struct rsbac_list_reg_item_t * item_p;
02944 
02945       /* first we must locate the item. */
02946       if ( (item_p = lookup_reg(handle)) )
02947         { /* ok, item was found */
02948           /* protect against reuse */
02949           item_p->self = NULL;
02950           if ( (reg_head.head == item_p) )
02951              { /* item is head */
02952                if ( (reg_head.tail == item_p) )
02953                  { /* item is head and tail = only item -> list will be empty*/
02954                    reg_head.head = NULL;
02955                    reg_head.tail = NULL;
02956                  }
02957                else
02958                  { /* item is head, but not tail -> next item becomes head */
02959                    item_p->next->prev = NULL;
02960                    reg_head.head = item_p->next;
02961                  }
02962              }
02963           else
02964              { /* item is not head */
02965                if ( (reg_head.tail == item_p) )
02966                  { /*item is not head, but tail -> previous item becomes tail*/
02967                    item_p->prev->next = NULL;
02968                    reg_head.tail = item_p->prev;
02969                  }
02970                else
02971                  { /* item is neither head nor tail -> item is cut out */
02972                    item_p->prev->next = item_p->next;
02973                    item_p->next->prev = item_p->prev;
02974                  }
02975              }
02976              
02977           /* curr is no longer valid -> reset */
02978           reg_head.curr=NULL;
02979           /* adjust counter */
02980           reg_head.count--;
02981           /* now we can remove the item from memory */
02982           clear_reg(item_p);
02983         }  /* end of if: item was found */
02984     }
02985 
02986 /* no locking needed */
02987 static void clear_lol_reg(struct rsbac_list_lol_reg_item_t * item_p)
02988     {
02989       if(item_p)
02990         {
02991           /* now we can remove the item from memory */
02992           remove_all_lol_items(item_p);
02993           if(item_p->def_data)
02994             rsbac_kfree(item_p->def_data);
02995           if(item_p->def_subdata)
02996             rsbac_kfree(item_p->def_subdata);
02997           rsbac_kfree(item_p);    
02998         }
02999     }
03000 
03001 /* locking needed */
03002 static void remove_lol_reg(struct rsbac_list_lol_reg_item_t *  handle)
03003     {
03004       struct rsbac_list_lol_reg_item_t * item_p;
03005 
03006       /* first we must locate the item. */
03007       if ( (item_p = lookup_lol_reg(handle)) )
03008         { /* ok, item was found */
03009           /* protect against reuse */
03010           item_p->self = NULL;
03011           if ( (lol_reg_head.head == item_p) )
03012              { /* item is head */
03013                if ( (lol_reg_head.tail == item_p) )
03014                  { /* item is head and tail = only item -> list will be empty*/
03015                    lol_reg_head.head = NULL;
03016                    lol_reg_head.tail = NULL;
03017                  }
03018                else
03019                  { /* item is head, but not tail -> next item becomes head */
03020                    item_p->next->prev = NULL;
03021                    lol_reg_head.head = item_p->next;
03022                  };
03023              }
03024           else
03025              { /* item is not head */
03026                if ( (lol_reg_head.tail == item_p) )
03027                  { /*item is not head, but tail -> previous item becomes tail*/
03028                    item_p->prev->next = NULL;
03029                    lol_reg_head.tail = item_p->prev;
03030                  }
03031                else
03032                  { /* item is neither head nor tail -> item is cut out */
03033                    item_p->prev->next = item_p->next;
03034                    item_p->next->prev = item_p->prev;
03035                  }
03036              }
03037              
03038           /* curr is no longer valid -> reset */
03039           lol_reg_head.curr=NULL;
03040           /* adjust counter */
03041           lol_reg_head.count--;
03042           /* now we can remove the item from memory */
03043           clear_lol_reg(item_p);
03044         }  /* end of if: item was found */
03045     }
03046 
03047 #if defined(CONFIG_RSBAC_LIST_REPL)
03048 inline void touch(struct rsbac_list_reg_item_t * list)
03049   {
03050     rsbac_get_current_nanotime(&list->lastchange);
03051   }
03052 #else
03053 #define touch(x)
03054 #endif
03055 
03056 #if defined(CONFIG_RSBAC_LIST_REPL)
03057 inline void lol_touch(struct rsbac_list_lol_reg_item_t * list)
03058   {
03059     rsbac_get_current_nanotime(&list->lastchange);
03060   }
03061 #else
03062 #define lol_touch(x)
03063 #endif
03064 
03065 /********************/
03066 /* Read/Write       */
03067 /********************/
03068 
03069 static int read_list(struct rsbac_list_reg_item_t * list)
03070   {
03071     struct file                   * file_p;
03072     int                             err = 0;
03073     int                             tmperr;
03074     int                             converr;
03075     rsbac_version_t                 list_version;
03076     u_long                          read_count = 0;
03077     u_long                          flags;
03078     char                          * old_buf;
03079     char                          * new_buf;
03080     char                          * old_data;
03081     char                          * new_data;
03082     struct rsbac_list_info_t      * list_info_p;
03083     rsbac_list_count_t              list_count;
03084     rsbac_time_t                    timestamp;
03085     struct rsbac_nanotime_t         lastchange;
03086     rsbac_time_t                    max_age = 0;
03087     rsbac_list_conv_function_t    * conv = NULL;
03088     rsbac_boolean_t                 timeout = FALSE;
03089     mm_segment_t                    oldfs;
03090 
03091     list_info_p = rsbac_kmalloc(sizeof(*list_info_p));
03092     if(!list_info_p)
03093       return -RSBAC_ENOMEM;
03094     file_p = rsbac_kmalloc(sizeof(*file_p));
03095     if(!file_p)
03096       {
03097         rsbac_kfree(list_info_p);
03098         return -RSBAC_ENOMEM;
03099       }
03100     /* open file */
03101     if ((err = rsbac_read_open(list->name,
03102                                file_p,
03103                                list->device) ))
03104       {
03105         rsbac_kfree(list_info_p);
03106         rsbac_kfree(file_p);
03107         return(err);
03108       }
03109 
03110     /* OK, now we can start reading */
03111     /* There is a read function for this file, so check info and read as
03112      * many items as possible. A positive return value means a read success,
03113      * 0 end of file and a negative value an error. */
03114 
03115     /* Set current user space to kernel space, because read() writes */
03116     /* to user space */
03117     oldfs = get_fs();
03118     set_fs(KERNEL_DS);
03119 
03120     /* check gen-list on-disk version */
03121     tmperr = file_p->f_op->read(file_p,
03122                              (__u8 *) &list_version,
03123                              sizeof(list_version),
03124                              &file_p->f_pos);
03125     set_fs(oldfs);
03126     /* error? */
03127     if (tmperr < sizeof(list_version))
03128       {
03129         rsbac_printk(KERN_WARNING
03130                "read_list(): read error from file!\n");
03131         err = -RSBAC_EREADFAILED;
03132         goto end_read;
03133       }
03134     /* if wrong list on-disk version, fail */
03135     switch(list_version)
03136       {
03137         case RSBAC_LIST_DISK_VERSION:
03138         case RSBAC_LIST_DISK_OLD_VERSION:
03139             break;
03140         default:
03141             rsbac_printk(KERN_WARNING
03142                    "read_list(): wrong on-disk list version %u in file %s, expected %u - error!\n",
03143                    list_version,
03144                    list->name,
03145                    RSBAC_LIST_DISK_VERSION);
03146             err = -RSBAC_EREADFAILED;
03147             goto end_read;
03148       }
03149 
03150     /* get timestamp */
03151     set_fs(KERNEL_DS);
03152     tmperr = file_p->f_op->read(file_p,
03153                              (__u8 *) &timestamp,
03154                              sizeof(timestamp),
03155                              &file_p->f_pos);
03156     set_fs(oldfs);
03157     /* error? */
03158     if (tmperr < sizeof(timestamp))
03159       {
03160         rsbac_printk(KERN_WARNING
03161                "read_list(): timestamp read error from file %s!\n",
03162                list->name);
03163         err = -RSBAC_EREADFAILED;
03164         goto end_read;
03165       }
03166 
03167     /* get list info */
03168     set_fs(KERNEL_DS);
03169     tmperr = file_p->f_op->read(file_p,
03170                              (__u8 *) list_info_p,
03171                              sizeof(*list_info_p),
03172                              &file_p->f_pos);
03173     set_fs(oldfs);
03174     /* error? */
03175     if (tmperr < sizeof(*list_info_p))
03176       {
03177         rsbac_printk(KERN_WARNING
03178                "read_list(): list info read error from file %s!\n",
03179                list->name);
03180         err = -RSBAC_EREADFAILED;
03181         goto end_read;
03182       }
03183 
03184     /* list timed out? System time is measured in seconds. */
03185     if(   list_info_p->max_age
03186        && (timestamp + list_info_p->max_age) <= RSBAC_CURRENT_TIME)
03187       timeout = TRUE;
03188 
03189     /* Valid key? */
03190     if (list_info_p->key != list->info.key)
03191       {
03192         if(timeout)
03193           {
03194             rsbac_printk(KERN_WARNING
03195                    "read_list(): accessing timed out list %s with wrong key, ignoring old contents!\n",
03196                    list->name);
03197             goto end_read;
03198           }
03199         else
03200           {
03201             rsbac_printk(KERN_WARNING
03202                    "read_list(): try to access list %s with wrong key!\n",
03203                    list->name);
03204             err = -EPERM;
03205             goto end_read;
03206           }
03207       }
03208 
03209     /* skip the rest, if ignore is requested */
03210     if(list->flags & RSBAC_LIST_IGNORE_OLD)
03211       goto end_read;
03212 
03213     switch(list_version)
03214       {
03215         case RSBAC_LIST_DISK_VERSION:
03216             set_fs(KERNEL_DS);
03217             tmperr = file_p->f_op->read(file_p,
03218                                         (char *) &lastchange,
03219                                         sizeof(lastchange),
03220                                         &file_p->f_pos);
03221             set_fs(oldfs);
03222             /* error? */
03223             if (tmperr < sizeof(lastchange))
03224               {
03225                 rsbac_printk(KERN_WARNING
03226                              "read_list(): lastchange read error from file %s!\n",
03227                              list->name);
03228                 err = -RSBAC_EREADFAILED;
03229                 goto end_read;
03230               }
03231 #if defined(CONFIG_RSBAC_LIST_REPL)
03232             else
03233               list->lastchange = lastchange;
03234 #endif
03235             break;
03236         case RSBAC_LIST_DISK_OLD_VERSION:
03237             break;
03238         default:
03239             break;
03240       }
03241     /* if wrong list version, try to get_conv */
03242     if(list_info_p->version != list->info.version)
03243       {
03244         if(list->get_conv)
03245           conv = list->get_conv(list_info_p->version);
03246         if(!conv)
03247           {
03248             if(timeout)
03249               {
03250                 rsbac_printk(KERN_WARNING
03251                        "read_list(): accessing timed out list %s without conversion function, ignoring old contents!\n",
03252                        list->name);
03253                 goto end_read;
03254               }
03255             else
03256               {
03257                 /* complain and set error, if ignore is not requested */
03258                 if(!(list->flags & RSBAC_LIST_IGNORE_UNSUPP_VERSION))
03259                   {
03260                     rsbac_printk(KERN_WARNING
03261                            "read_list(): cannot convert list version %u of file %s to version %u!\n",
03262                            list_info_p->version,
03263                            list->name,
03264                            list->info.version);
03265                     err = -RSBAC_EINVALIDVERSION;
03266                   }
03267                 goto end_read;
03268               }
03269           }
03270         else
03271           {
03272             rsbac_printk(KERN_WARNING
03273                    "read_list(): converting list version %u of file %s on device %02u:%02u to version %u!\n",
03274                    list_info_p->version,
03275                    list->name,
03276                    RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device),
03277                    list->info.version);
03278           }
03279       }
03280     else /* same version needs same sizes */
03281       {
03282         if(   (list_info_p->desc_size != list->info.desc_size)
03283            || (list_info_p->data_size != list->info.data_size)
03284           )
03285           {
03286             if(timeout)
03287               {
03288                 rsbac_printk(KERN_WARNING
03289                        "read_list(): accessing timed out list %s with wrong desc or data size, ignoring old contents!\n",
03290                        list->name);
03291                 goto end_read;
03292               }
03293             else
03294               {
03295                 rsbac_printk(KERN_WARNING
03296                        "read_list(): desc or data size mismatch on list %s!\n",
03297                        list->name);
03298                 err = -RSBAC_EINVALIDVALUE;
03299                 goto end_read;
03300               }
03301           }
03302       }
03303 
03304     /* get list count */
03305     set_fs(KERNEL_DS);
03306     tmperr = file_p->f_op->read(file_p,
03307                              (__u8 *) &list_count,
03308                              sizeof(list_count),
03309                              &file_p->f_pos);
03310     set_fs(oldfs);
03311     /* error? */
03312     if (tmperr < sizeof(list_count))
03313       {
03314         rsbac_printk(KERN_WARNING
03315                "read_list(): list count read error from file %s!\n",
03316                list->name);
03317         err = -RSBAC_EREADFAILED;
03318         goto end_read;
03319       }
03320 
03321     /* alloc mem for old and converted item */
03322     old_buf = rsbac_kmalloc(list_info_p->desc_size + list_info_p->data_size);
03323     if(!old_buf)
03324       {
03325         rsbac_printk(KERN_WARNING
03326                "read_list(): cannot allocate memory!\n");
03327         err = -RSBAC_ENOMEM;
03328         goto end_read;
03329       }
03330     new_buf = rsbac_kmalloc(list->info.desc_size + list->info.data_size);
03331     if(!new_buf)
03332       {
03333         rsbac_printk(KERN_WARNING
03334                "read_list(): cannot allocate memory!\n");
03335         rsbac_kfree(old_buf);
03336         err = -RSBAC_ENOMEM;
03337         goto end_read;
03338       }
03339     /* calculate data pointers */
03340     if(list_info_p->data_size)
03341       old_data = old_buf + list_info_p->desc_size;
03342     else
03343       old_data = NULL;
03344     if(list->info.data_size)
03345       new_data = new_buf + list->info.desc_size;
03346     else
03347       new_data = NULL;
03348 
03349     /* actual reading */
03350     do
03351       {
03352         set_fs(KERNEL_DS);
03353         tmperr = file_p->f_op->read(file_p,
03354                                     (char *) &max_age,
03355                                     sizeof(max_age),
03356                                     &file_p->f_pos);
03357         set_fs(oldfs);
03358         if(conv)
03359           {
03360             set_fs(KERNEL_DS);
03361             tmperr = file_p->f_op->read(file_p,
03362                                      old_buf,
03363                                      list_info_p->desc_size + list_info_p->data_size,
03364                                      &file_p->f_pos);
03365             set_fs(oldfs);
03366             if(tmperr > 0)
03367               { /* convert */
03368                 converr = conv(old_buf, old_data,
03369                                new_buf, new_data);
03370                 if(converr)
03371                   tmperr = converr;
03372               }
03373           }
03374         else
03375           {
03376             set_fs(KERNEL_DS);
03377             tmperr = file_p->f_op->read(file_p,
03378                                      new_buf,
03379                                      list->info.desc_size + list->info.data_size,
03380                                      &file_p->f_pos);
03381             set_fs(oldfs);
03382           }
03383         /* if successful, add item */
03384         if (tmperr > 0)
03385           {
03386             /* wait for write access to list */
03387             rsbac_write_lock(&list->lock, &flags);
03388             add_item(list, max_age, new_buf, new_data);
03389             /* allow access */
03390             rsbac_write_unlock(&list->lock, &flags);
03391             read_count++;
03392 /*
03393 #ifdef CONFIG_RSBAC_DEBUG
03394                 if (rsbac_debug_lists) rsbac_printk(KERN_DEBUG "read_list(): read item %i\n",
03395                      user_aci.id);
03396 #endif
03397 */
03398           }
03399       }
03400     while (tmperr > 0); /* end of do */
03401 
03402     if (tmperr < 0)
03403       {
03404         rsbac_printk(KERN_WARNING "read_list(): read error from file %s!\n",
03405                list->name);
03406         err = -RSBAC_EREADFAILED;
03407       }
03408     rsbac_kfree(old_buf);
03409     rsbac_kfree(new_buf);
03410 
03411     if (read_count != list_count)
03412       {
03413         rsbac_printk(KERN_WARNING "read_list(): read %lu, expected %u items from file %s!\n",
03414                read_count,
03415                list_count,
03416                list->name);
03417         err = -RSBAC_EREADFAILED;
03418       }
03419 
03420 end_read:
03421 
03422 #ifdef CONFIG_RSBAC_DEBUG
03423     if (rsbac_debug_lists)
03424       {
03425         rsbac_printk(KERN_DEBUG "read_list(): %lu entries read.\n",
03426                read_count);
03427       }
03428 #endif
03429     /* We do not need this file any more */
03430     rsbac_read_close(file_p);
03431     rsbac_kfree(list_info_p);
03432     rsbac_kfree(file_p);
03433     return(err);
03434   }
03435 
03436 
03437 static int read_lol_list(struct rsbac_list_lol_reg_item_t * list)
03438   {
03439     struct file                   * file_p;
03440     int                             err = 0;
03441     int                             tmperr;
03442     int                             converr;
03443     rsbac_version_t                 list_version;
03444     u_long                          read_count = 0;
03445     u_long                          flags;
03446     u_long                          sublen;
03447     u_long                          i;
03448     char                          * old_buf;
03449     char                          * new_buf;
03450     char                          * old_data;
03451     char                          * new_data;
03452     char                          * old_subbuf;
03453     char                          * new_subbuf;
03454     char                          * old_subdata;
03455     char                          * new_subdata;
03456     struct rsbac_list_lol_info_t  * list_info_p;
03457     rsbac_list_count_t              list_count;
03458     rsbac_time_t                    timestamp;
03459     struct rsbac_nanotime_t         lastchange;
03460     rsbac_time_t                    max_age = 0;
03461     rsbac_list_conv_function_t    * conv = NULL;
03462     rsbac_list_conv_function_t    * subconv = NULL;
03463     rsbac_boolean_t                 timeout = FALSE;
03464     struct rsbac_list_lol_item_t  * item_p;
03465     mm_segment_t                    oldfs;
03466 
03467     list_info_p = rsbac_kmalloc(sizeof(*list_info_p));
03468     if(!list_info_p)
03469       return -RSBAC_ENOMEM;
03470     file_p = rsbac_kmalloc(sizeof(*file_p));
03471     if(!file_p)
03472       {
03473         rsbac_kfree(list_info_p);
03474         return -RSBAC_ENOMEM;
03475       }
03476     /* open file */
03477     if ((err = rsbac_read_open(list->name,
03478                                file_p,
03479                                list->device) ))
03480       {
03481         rsbac_kfree(list_info_p);
03482         rsbac_kfree(file_p);
03483         return(err);
03484       }
03485 
03486     /* OK, now we can start reading */
03487     /* There is a read function for this file, so check info and read as
03488      * many items as possible. A positive return value means a read success,
03489      * 0 end of file and a negative value an error. */
03490 
03491     /* Set current user space to kernel space, because read() writes */
03492     /* to user space */
03493     oldfs = get_fs();
03494     set_fs(KERNEL_DS);
03495 
03496     /* check gen-list on-disk version */
03497     tmperr = file_p->f_op->read(file_p,
03498                              (__u8 *) &list_version,
03499                              sizeof(list_version),
03500                              &file_p->f_pos);
03501     set_fs(oldfs);
03502     /* error? */
03503     if (tmperr < sizeof(list_version))
03504       {
03505         printk(KERN_WARNING
03506                "read_lol_list(): read error from file!\n");
03507         err = -RSBAC_EREADFAILED;
03508         goto end_read;
03509       }
03510     /* if wrong list on-disk version, fail */
03511     switch(list_version)
03512       {
03513         case RSBAC_LIST_DISK_VERSION:
03514         case RSBAC_LIST_DISK_OLD_VERSION:
03515             break;
03516         default:
03517             rsbac_printk(KERN_WARNING
03518                    "read_lol_list(): wrong on-disk list version %u in file %s, expected %u - error!\n",
03519                    list_version,
03520                    list->name,
03521                    RSBAC_LIST_DISK_VERSION);
03522             err = -RSBAC_EREADFAILED;
03523             goto end_read;
03524       }
03525 
03526     /* get timestamp */
03527     set_fs(KERNEL_DS);
03528     tmperr = file_p->f_op->read(file_p,
03529                              (__u8 *) &timestamp,
03530                              sizeof(timestamp),
03531                              &file_p->f_pos);
03532     set_fs(oldfs);
03533     /* error? */
03534     if (tmperr < sizeof(timestamp))
03535       {
03536         rsbac_printk(KERN_WARNING
03537                "read_lol_list(): timestamp read error from file %s!\n",
03538                list->name);
03539         err = -RSBAC_EREADFAILED;
03540         goto end_read;
03541       }
03542 
03543     /* get list info */
03544     set_fs(KERNEL_DS);
03545     tmperr = file_p->f_op->read(file_p,
03546                              (__u8 *) list_info_p,
03547                              sizeof(*list_info_p),
03548                              &file_p->f_pos);
03549     set_fs(oldfs);
03550     /* error? */
03551     if (tmperr < sizeof(*list_info_p))
03552       {
03553         rsbac_printk(KERN_WARNING
03554                "read_lol_list(): list info read error from file %s!\n",
03555                list->name);
03556         err = -RSBAC_EREADFAILED;
03557         goto end_read;
03558       }
03559 
03560     /* list timed out? System time is measured in seconds. */
03561     if(   list_info_p->max_age
03562        && (timestamp + list_info_p->max_age) <= RSBAC_CURRENT_TIME)
03563       timeout = TRUE;
03564 
03565     /* Valid key? */
03566     if (list_info_p->key != list->info.key)
03567       {
03568         if(timeout)
03569           {
03570             rsbac_printk(KERN_WARNING
03571                    "read_lol_list(): accessing timed out list %s with wrong key, ignoring old contents!\n",
03572                    list->name);
03573             goto end_read;
03574           }
03575         else
03576           {
03577             rsbac_printk(KERN_WARNING
03578                    "read_lol_list(): try to access list %s with wrong key!\n",
03579                    list->name);
03580             err = -EPERM;
03581             goto end_read;
03582           }
03583       }
03584 
03585     /* skip the rest, if ignore is requested */
03586     if(list->flags & RSBAC_LIST_IGNORE_OLD)
03587       goto end_read;
03588 
03589     switch(list_version)
03590       {
03591         case RSBAC_LIST_DISK_VERSION:
03592             set_fs(KERNEL_DS);
03593             tmperr = file_p->f_op->read(file_p,
03594                                         (char *) &lastchange,
03595                                         sizeof(lastchange),
03596                                         &file_p->f_pos);
03597             set_fs(oldfs);
03598             /* error? */
03599             if (tmperr < sizeof(lastchange))
03600               {
03601                 rsbac_printk(KERN_WARNING
03602                              "read_list(): lastchange read error from file %s!\n",
03603                              list->name);
03604                 err = -RSBAC_EREADFAILED;
03605                 goto end_read;
03606               }
03607 #if defined(CONFIG_RSBAC_LIST_REPL)
03608             else
03609               list->lastchange = lastchange;
03610 #endif
03611             break;
03612         case RSBAC_LIST_DISK_OLD_VERSION:
03613             break;
03614         default:
03615             break;
03616       }
03617     /* if wrong list version, try to get_conv */
03618     if(list_info_p->version != list->info.version)
03619       {
03620         if(list->get_conv)
03621           conv = list->get_conv(list_info_p->version);
03622         if(list->get_subconv)
03623           subconv = list->get_subconv(list_info_p->version);
03624         if(!conv || !subconv)
03625           {
03626             if(timeout)
03627               {
03628                 rsbac_printk(KERN_WARNING
03629                        "read_lol_list(): accessing timed out list %s without both conversion functions, ignoring old contents!\n",
03630                        list->name);
03631                 goto end_read;
03632               }
03633             else
03634               {
03635                 /* complain and set error, if ignore is not requested */
03636                 if(!(list->flags & RSBAC_LIST_IGNORE_UNSUPP_VERSION))
03637                   {
03638                     rsbac_printk(KERN_WARNING
03639                            "read_lol_list(): cannot convert list version %u of file %s to version %u!\n",
03640                            list_info_p->version,
03641                            list->name,
03642                            list->info.version);
03643                     err = -RSBAC_EINVALIDVERSION;
03644                   }
03645                 goto end_read;
03646               }
03647           }
03648         else
03649           {
03650             rsbac_printk(KERN_WARNING
03651                    "read_lol_list(): converting list version %u of file %s on device %02u:%02u to version %u!\n",
03652                    list_info_p->version,
03653                    list->name,
03654                    RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device),
03655                    list->info.version);
03656           }
03657       }
03658     else /* same version needs same sizes */
03659       {
03660         if(   (list_info_p->desc_size != list->info.desc_size)
03661            || (list_info_p->data_size != list->info.data_size)
03662            || (list_info_p->subdesc_size != list->info.subdesc_size)
03663            || (list_info_p->subdata_size != list->info.subdata_size)
03664           )
03665           {
03666             if(timeout)
03667               {
03668                 rsbac_printk(KERN_WARNING
03669                        "read_lol_list(): accessing timed out list %s with wrong desc or data size(s), ignoring old contents!\n",
03670                        list->name);
03671                 goto end_read;
03672               }
03673             else
03674               {
03675                 rsbac_printk(KERN_WARNING
03676                        "read_lol_list(): desc or data size mismatch on list %s!\n",
03677                        list->name);
03678                 err = -RSBAC_EINVALIDVALUE;
03679                 goto end_read;
03680               }
03681           }
03682       }
03683 
03684     /* get list count */
03685     set_fs(KERNEL_DS);
03686     tmperr = file_p->f_op->read(file_p,
03687                              (__u8 *) &list_count,
03688                              sizeof(list_count),
03689                              &file_p->f_pos);
03690     set_fs(oldfs);
03691     /* error? */
03692     if (tmperr < sizeof(list_count))
03693       {
03694         rsbac_printk(KERN_WARNING
03695                "read_lol_list(): list count read error from file %s!\n",
03696                list->name);
03697         err = -RSBAC_EREADFAILED;
03698         goto end_read;
03699       }
03700 
03701     /* alloc mem for old and converted items */
03702     old_buf = rsbac_kmalloc(list_info_p->desc_size + list_info_p->data_size);
03703     if(!old_buf)
03704       {
03705         rsbac_printk(KERN_WARNING
03706                "read_lol_list(): cannot allocate memory!\n");
03707         err = -RSBAC_ENOMEM;
03708         goto end_read;
03709       }
03710     new_buf = rsbac_kmalloc(list->info.desc_size + list->info.data_size);
03711     if(!new_buf)
03712       {
03713         rsbac_printk(KERN_WARNING
03714                "read_lol_list(): cannot allocate memory!\n");
03715         rsbac_kfree(old_buf);
03716         err = -RSBAC_ENOMEM;
03717         goto end_read;
03718       }
03719     old_subbuf = rsbac_kmalloc(list_info_p->subdesc_size + list_info_p->subdata_size);
03720     if(!old_subbuf)
03721       {
03722         rsbac_printk(KERN_WARNING
03723                "read_lol_list(): cannot allocate memory!\n");
03724         rsbac_kfree(old_buf);
03725         rsbac_kfree(new_buf);
03726         err = -RSBAC_ENOMEM;
03727         goto end_read;
03728       }
03729     new_subbuf = rsbac_kmalloc(list->info.subdesc_size + list->info.subdata_size);
03730     if(!new_subbuf)
03731       {
03732         rsbac_printk(KERN_WARNING
03733                "read_lol_list(): cannot allocate memory!\n");
03734         rsbac_kfree(old_buf);
03735         rsbac_kfree(new_buf);
03736         rsbac_kfree(old_subbuf);
03737         err = -RSBAC_ENOMEM;
03738         goto end_read;
03739       }
03740     /* calculate data pointers */
03741     if(list_info_p->data_size)
03742       old_data = old_buf + list_info_p->desc_size;
03743     else
03744       old_data = NULL;
03745     if(list->info.data_size)
03746       new_data = new_buf + list->info.desc_size;
03747     else
03748       new_data = NULL;
03749     if(list_info_p->subdata_size)
03750       old_subdata = old_subbuf + list_info_p->subdesc_size;
03751     else
03752       old_subdata = NULL;
03753     if(list->info.subdata_size)
03754       new_subdata = new_subbuf + list->info.subdesc_size;
03755     else
03756       new_subdata = NULL;
03757 
03758     /* actual reading */
03759     do
03760       {
03761         set_fs(KERNEL_DS);
03762         tmperr = file_p->f_op->read(file_p,
03763                                     (char *) &max_age,
03764                                     sizeof(max_age),
03765                                     &file_p->f_pos);
03766         set_fs(oldfs);
03767         if(conv)
03768           {
03769             set_fs(KERNEL_DS);
03770             tmperr = file_p->f_op->read(file_p,
03771                                      old_buf,
03772                                      list_info_p->desc_size + list_info_p->data_size,
03773                                      &file_p->f_pos);
03774             set_fs(oldfs);
03775             if(tmperr > 0)
03776               { /* convert */
03777                 converr = conv(old_buf, old_data,
03778                                new_buf, new_data);
03779                 if(converr)
03780                   tmperr = converr;
03781               }
03782           }
03783         else
03784           {
03785             set_fs(KERNEL_DS);
03786             tmperr = file_p->f_op->read(file_p,
03787                                      new_buf,
03788                                      list->info.desc_size + list->info.data_size,
03789                                      &file_p->f_pos);
03790             set_fs(oldfs);
03791           }
03792         /* if successful, add item */
03793         if (tmperr > 0)
03794           {
03795             /* wait for write access to list */
03796             rsbac_write_lock(&list->lock, &flags);
03797             item_p = add_lol_item(list, max_age, new_buf, new_data);
03798             /* allow access */
03799             rsbac_write_unlock(&list->lock, &flags);
03800             if(!item_p)
03801               {
03802                 err = -RSBAC_ENOMEM;
03803                 goto end_read_free;
03804               }
03805             read_count++;
03806 /*
03807 #ifdef CONFIG_RSBAC_DEBUG
03808                 if (rsbac_debug_lists) rsbac_printk(KERN_DEBUG "read_lol_list(): read item %i\n",
03809                      user_aci.id);
03810 #endif
03811 */
03812             set_fs(KERNEL_DS);
03813             tmperr = file_p->f_op->read(file_p,
03814                                      (__u8 *) &sublen,
03815                                      sizeof(sublen),
03816                                      &file_p->f_pos);
03817             set_fs(oldfs);
03818             /* if successful, read and add sublen subitems */
03819             if (tmperr > 0)
03820               {
03821                 for(i=0;i<sublen;i++)
03822                   {
03823                     set_fs(KERNEL_DS);
03824                     tmperr = file_p->f_op->read(file_p,
03825                                                 (char *) &max_age,
03826                                                 sizeof(max_age),
03827                                                 &file_p->f_pos);
03828                     set_fs(oldfs);
03829                     if(subconv)
03830                       {
03831                         set_fs(KERNEL_DS);
03832                         tmperr = file_p->f_op->read(file_p,
03833                                                  old_subbuf,
03834                                                  list_info_p->subdesc_size + list_info_p->subdata_size,
03835                                                  &file_p->f_pos);
03836                         set_fs(oldfs);
03837                         if(tmperr > 0)
03838                           { /* convert */
03839                             converr = subconv(old_subbuf, old_subdata,
03840                                               new_subbuf, new_subdata);
03841                             if(converr)
03842                               tmperr = converr;
03843                           }
03844                       }
03845                     else
03846                       {
03847                         set_fs(KERNEL_DS);
03848                         tmperr = file_p->f_op->read(file_p,
03849                                                  new_subbuf,
03850                                                  list->info.subdesc_size + list->info.subdata_size,
03851                                                  &file_p->f_pos);
03852                         set_fs(oldfs);
03853                       }
03854                     if(tmperr > 0)
03855                       {
03856                         /* wait for write access to list */
03857                         rsbac_write_lock(&list->lock, &flags);
03858                         if (!add_lol_subitem(list,
03859                                              item_p,
03860                                              max_age,
03861                                              new_subbuf,
03862                                              new_subdata))
03863                           {
03864                             rsbac_printk(KERN_WARNING
03865                                    "read_lol_list(): could not add subitem!\n");
03866                             i = sublen;
03867                             tmperr = -1;
03868                           }
03869                         /* allow access */
03870                         rsbac_write_unlock(&list->lock, &flags);
03871                       }
03872                     else
03873                       {
03874                         i = sublen;
03875                         tmperr = -1;
03876                       }
03877                   }
03878               }
03879           }
03880       }
03881     while (tmperr > 0); /* end of do */
03882 
03883     if (tmperr < 0)
03884       {
03885         rsbac_printk(KERN_WARNING "read_lol_list(): read error from file %s!\n",
03886                list->name);
03887         err = -RSBAC_EREADFAILED;
03888       }
03889 
03890     if (read_count != list_count)
03891       {
03892         rsbac_printk(KERN_WARNING "read_lol_list(): read %lu, expected %u items from file %s!\n",
03893                read_count,
03894                list_count,
03895                list->name);
03896         err = -RSBAC_EREADFAILED;
03897       }
03898 
03899 end_read_free:
03900     rsbac_kfree(old_buf);
03901     rsbac_kfree(new_buf);
03902     rsbac_kfree(old_subbuf);
03903     rsbac_kfree(new_subbuf);
03904 
03905 end_read:
03906 
03907 #ifdef CONFIG_RSBAC_DEBUG
03908     if (rsbac_debug_lists)
03909       {
03910         rsbac_printk(KERN_DEBUG "read_lol_list(): %lu entries read.\n",
03911                read_count);
03912       }
03913 #endif
03914     /* We do not need this file any more */
03915     rsbac_read_close(file_p);
03916     rsbac_kfree(list_info_p);
03917     rsbac_kfree(file_p);
03918     return(err);
03919   } /* end of read_lol_list() */
03920 
03921 
03922 #ifndef CONFIG_RSBAC_NO_WRITE
03923 static int fill_buffer(struct rsbac_list_reg_item_t * list,
03924                        struct rsbac_list_write_item_t ** write_item_pp)
03925   {
03926     struct rsbac_list_write_item_t * write_item_p;
03927     struct rsbac_list_item_t * current_p;
03928            u_long              flags;
03929            char              * buffer = NULL;
03930            u_long              buflen;
03931            u_long              write_count = 0;
03932            rsbac_boolean_t     vmalloc_used = FALSE;
03933            rsbac_version_t     list_version = RSBAC_LIST_DISK_VERSION;
03934            rsbac_time_t        timestamp = RSBAC_CURRENT_TIME;
03935 
03936     write_item_p = rsbac_kmalloc(sizeof(*write_item_p));
03937     if(!write_item_p)
03938       {
03939         *write_item_pp = NULL;
03940         return(-RSBAC_ENOMEM);
03941       }
03942 
03943     /* protect this list */
03944     rsbac_read_lock(&list->lock, &flags);
03945     /* allocate mem */
03946     buflen =   sizeof(list_version)
03947              + sizeof(timestamp)
03948              + sizeof(list->info)
03949              + sizeof(list->lastchange)
03950              + sizeof(list->count)
03951              + list->count * (sizeof(current_p->max_age) + list->info.desc_size + list->info.data_size);
03952     /* try to rsbac_vkmalloc */
03953     buffer = (char *) rsbac_vkmalloc(buflen, &vmalloc_used);
03954     if(!buffer)
03955       {
03956         /* unprotect this list */
03957         rsbac_read_unlock(&list->lock, &flags);
03958         rsbac_kfree(write_item_p);
03959         *write_item_pp = NULL;
03960         return(-RSBAC_ENOMEM);
03961       }
03962     /* copy version */
03963     memcpy(buffer,
03964            (char *) &list_version,
03965            sizeof(list_version));
03966     write_count = sizeof(list_version);
03967     /* copy timestamp */
03968     memcpy(buffer+write_count,
03969            (char *) &timestamp,
03970            sizeof(timestamp));
03971     write_count += sizeof(timestamp);
03972     /* copy info */
03973     memcpy(buffer+write_count,
03974            (char *) &list->info,
03975            sizeof(list->info));
03976     write_count += sizeof(list->info);
03977     /* copy lastchange */
03978     memcpy(buffer+write_count,
03979            (char *) &list->lastchange,
03980            sizeof(list->lastchange));
03981     write_count += sizeof(list->lastchange);
03982     /* copy count */
03983     memcpy(buffer+write_count,
03984            (char *) &list->count,
03985            sizeof(list->count));
03986     write_count += sizeof(list->count);
03987     /* copy list */
03988     current_p = list->head;
03989     while (current_p) 
03990       {
03991         memcpy(buffer+write_count,
03992                &current_p->max_age,
03993                sizeof(current_p->max_age));
03994         write_count += sizeof(current_p->max_age);
03995         memcpy(buffer+write_count,
03996                ((char *) current_p) + sizeof(*current_p),
03997                list->info.desc_size + list->info.data_size);
03998         write_count += list->info.desc_size + list->info.data_size;
03999         current_p = current_p->next;
04000       }
04001 
04002     /* fill write_item */
04003     write_item_p->prev = NULL;
04004     write_item_p->next = NULL;
04005     write_item_p->list = list;
04006     write_item_p->buflen = write_count;
04007     write_item_p->buf = buffer;
04008     write_item_p->vmalloc_used = vmalloc_used;
04009     strncpy(write_item_p->name, list->name, RSBAC_LIST_MAX_FILENAME);
04010     write_item_p->name[RSBAC_LIST_MAX_FILENAME] = 0;
04011     write_item_p->device = list->device;
04012 
04013     *write_item_pp = write_item_p;
04014 
04015     /* unprotect this list */
04016     rsbac_read_unlock(&list->lock, &flags);
04017 
04018     return 0;
04019   }
04020 
04021 static int rsbac_list_write_buffers(struct rsbac_list_write_head_t write_head,
04022                          rsbac_boolean_t need_lock)
04023   {
04024     struct file              * file_p;
04025            int                 count = 0;
04026            mm_segment_t        oldfs;
04027            u_long              written;
04028            u_long              bytes;
04029            int                 tmperr = 0;
04030     struct rsbac_list_write_item_t * write_item_p;
04031     struct rsbac_list_write_item_t * next_item_p;
04032 
04033     file_p = rsbac_kmalloc(sizeof(*file_p));
04034     if(!file_p)
04035       {
04036         return -RSBAC_ENOMEM;
04037       }
04038     write_item_p = write_head.head;
04039     while(write_item_p)
04040       {
04041     #ifdef CONFIG_RSBAC_DEBUG
04042         if (rsbac_debug_write)
04043           {
04044             rsbac_printk(KERN_DEBUG "rsbac_list_write_buffers(): write list %s on device %02u:%02u.\n",
04045                    write_item_p->name,
04046                    RSBAC_MAJOR(write_item_p->device),
04047                    RSBAC_MINOR(write_item_p->device));
04048           }
04049     #endif
04050         if(need_lock)
04051           lock_kernel();
04052         /* open file */
04053         if ((tmperr = rsbac_write_open(write_item_p->name,
04054                                        file_p,
04055                                        write_item_p->device) ))
04056           {
04057             if(tmperr != -RSBAC_ENOTWRITABLE)
04058               {
04059                 rsbac_printk(KERN_WARNING
04060                        "rsbac_list_write_buffers(): opening file %s on device %02u:%02u failed with error %i!\n",
04061                        write_item_p->name,
04062                        RSBAC_MAJOR(write_item_p->device),
04063                        RSBAC_MINOR(write_item_p->device),
04064                        tmperr);
04065               }
04066             count = tmperr;
04067             goto free_item;
04068           }
04069 
04070         /* OK, now we can start writing the buffer. */
04071         /* Set current user space to kernel space, because write() reads    */
04072         /* from user space */
04073         oldfs = get_fs();
04074         set_fs(KERNEL_DS);
04075     
04076         written = 0;
04077         while ((written < write_item_p->buflen) && (tmperr >= 0)) 
04078           {
04079             bytes = rsbac_min(write_item_p->buflen - written, RSBAC_MAX_WRITE_CHUNK);
04080             tmperr = file_p->f_op->write(file_p,
04081                                       write_item_p->buf + written,
04082                                       bytes,
04083                                       &file_p->f_pos);
04084             if(tmperr > 0)
04085               {
04086                 written += tmperr;
04087               }
04088           }
04089         if (tmperr < 0)
04090           {
04091             rsbac_printk(KERN_WARNING
04092                    "rsbac_list_write_buffers(): write error %i on device %02u:%02u file %s!\n",
04093                    tmperr,
04094                    RSBAC_MAJOR(write_item_p->device),
04095                    RSBAC_MINOR(write_item_p->device),
04096                    write_item_p->name);
04097             if(write_item_p->list->self == write_item_p->list)
04098               write_item_p->list->dirty = TRUE;
04099           }
04100         else
04101           count++;
04102 
04103         /* Set current user space back to user space, because write() reads */
04104         /* from user space */
04105         set_fs(oldfs);
04106     
04107     #ifdef CONFIG_RSBAC_DEBUG
04108         if (rsbac_debug_write)
04109           {
04110             rsbac_printk(KERN_DEBUG "rsbac_list_write_buffers(): %lu bytes written.\n",
04111                    written);
04112           }
04113     #endif
04114         /* End of write access */
04115         rsbac_write_close(file_p);
04116 
04117 free_item:
04118         if(need_lock)
04119           unlock_kernel();
04120         /* free buffer */
04121         rsbac_vkfree(write_item_p->buf, write_item_p->vmalloc_used);
04122         next_item_p = write_item_p->next;
04123         rsbac_kfree(write_item_p);
04124         write_item_p = next_item_p;
04125       }
04126     /* Ready. */
04127     rsbac_kfree(file_p);
04128     return count;
04129   }
04130 
04131 static int fill_lol_buffer(struct rsbac_list_lol_reg_item_t * list,
04132                            struct rsbac_list_lol_write_item_t ** write_item_pp)
04133   {
04134     struct rsbac_list_lol_write_item_t * write_item_p;
04135     struct rsbac_list_lol_item_t       * current_p;
04136     struct rsbac_list_item_t           * sub_p;
04137            u_long              flags;
04138            char              * buffer = NULL;
04139            u_long              buflen;
04140            u_long              write_count = 0;
04141            rsbac_boolean_t     vmalloc_used = FALSE;
04142            rsbac_version_t     list_version = RSBAC_LIST_DISK_VERSION;
04143            rsbac_time_t        timestamp = RSBAC_CURRENT_TIME;
04144 
04145     write_item_p = rsbac_kmalloc(sizeof(*write_item_p));
04146     if(!write_item_p)
04147       {
04148         *write_item_pp = NULL;
04149         return(-RSBAC_ENOMEM);
04150       }
04151 
04152     /* protect this list */
04153     rsbac_read_lock(&list->lock, &flags);
04154 
04155     /* allocate mem */
04156     buflen =   sizeof(list_version)
04157              + sizeof(timestamp)
04158              + sizeof(list->info)
04159              + sizeof(list->lastchange)
04160              + sizeof(list->count)
04161              + list->count * (sizeof(current_p->max_age) + list->info.desc_size + list->info.data_size);
04162     current_p = list->head;
04163     while(current_p)
04164       {
04165         buflen += sizeof(current_p->count);
04166         buflen += current_p->count * (sizeof(current_p->max_age) + list->info.subdesc_size + list->info.subdata_size);
04167         current_p = current_p->next;
04168       }
04169     /* try to rsbac_vkmalloc */
04170     buffer = (char *) rsbac_vkmalloc(buflen, &vmalloc_used);
04171     if(!buffer)
04172       {
04173         /* unprotect this list */
04174         rsbac_read_unlock(&list->lock, &flags);
04175         rsbac_kfree(write_item_p);
04176         *write_item_pp = NULL;
04177         return(-RSBAC_ENOMEM);
04178       }
04179     /* copy version */
04180     memcpy(buffer,
04181            (char *) &list_version,
04182            sizeof(list_version));
04183     write_count = sizeof(list_version);
04184     /* copy timestamp */
04185     memcpy(buffer+write_count,
04186            (char *) &timestamp,
04187            sizeof(timestamp));
04188     write_count += sizeof(timestamp);
04189     /* copy info */
04190     memcpy(buffer+write_count,
04191            (char *) &list->info,
04192            sizeof(list->info));
04193     write_count += sizeof(list->info);
04194     /* copy lastchange */
04195     memcpy(buffer+write_count,
04196            (char *) &list->lastchange,
04197            sizeof(list->lastchange));
04198     write_count += sizeof(list->lastchange);
04199     /* copy count */
04200     memcpy(buffer+write_count,
04201            (char *) &list->count,
04202            sizeof(list->count));
04203     write_count += sizeof(list->count);
04204     /* copy list */
04205     current_p = list->head;
04206     while (current_p) 
04207       {
04208         memcpy(buffer+write_count,
04209                &current_p->max_age,
04210                sizeof(current_p->max_age));
04211         write_count += sizeof(current_p->max_age);
04212         memcpy(buffer+write_count,
04213                ((char *) current_p) + sizeof(*current_p),
04214                list->info.desc_size + list->info.data_size);
04215         write_count += list->info.desc_size + list->info.data_size;
04216         memcpy(buffer+write_count,
04217                &current_p->count,
04218                sizeof(current_p->count));
04219         write_count += sizeof(current_p->count);
04220         /* copy subitems */
04221         sub_p = current_p->head;
04222         while (sub_p) 
04223           {
04224             memcpy(buffer+write_count,
04225                    &sub_p->max_age,
04226                    sizeof(sub_p->max_age));
04227             write_count += sizeof(sub_p->max_age);
04228             memcpy(buffer+write_count,
04229                    ((char *) sub_p) + sizeof(*sub_p),
04230                    list->info.subdesc_size + list->info.subdata_size);
04231             write_count += list->info.subdesc_size + list->info.subdata_size;
04232             sub_p = sub_p->next;
04233           }
04234         current_p = current_p->next;
04235       }
04236 
04237     /* fill write_item */
04238     write_item_p->prev = NULL;
04239     write_item_p->next = NULL;
04240     write_item_p->list = list;
04241     write_item_p->buflen = write_count;
04242     write_item_p->buf = buffer;
04243     write_item_p->vmalloc_used = vmalloc_used;
04244     strncpy(write_item_p->name, list->name, RSBAC_LIST_MAX_FILENAME);
04245     write_item_p->name[RSBAC_LIST_MAX_FILENAME] = 0;
04246     write_item_p->device = list->device;
04247     *write_item_pp = write_item_p;
04248 
04249     /* unprotect this list */
04250     rsbac_read_unlock(&list->lock, &flags);
04251 
04252     return 0;
04253   }
04254 
04255 static int rsbac_list_write_lol_buffers(struct rsbac_list_lol_write_head_t write_head,
04256                              rsbac_boolean_t need_lock)
04257   {
04258     struct file              * file_p;
04259            int                 count = 0;
04260            mm_segment_t        oldfs;
04261            u_long              written;
04262            u_long              bytes;
04263            int                 tmperr = 0;
04264     struct rsbac_list_lol_write_item_t * write_item_p;
04265     struct rsbac_list_lol_write_item_t * next_item_p;
04266 
04267     file_p = rsbac_kmalloc(sizeof(*file_p));
04268     if(!file_p)
04269       {
04270         return -RSBAC_ENOMEM;
04271       }
04272     write_item_p = write_head.head;
04273     while(write_item_p)
04274       {
04275     #ifdef CONFIG_RSBAC_DEBUG
04276         if (rsbac_debug_write)
04277           {
04278             rsbac_printk(KERN_DEBUG "rsbac_list_write_lol_buffers(): write list %s on device %02u:%02u.\n",
04279                    write_item_p->name,
04280                    RSBAC_MAJOR(write_item_p->device),
04281                    RSBAC_MINOR(write_item_p->device));
04282           }
04283     #endif
04284         if(need_lock)
04285           lock_kernel();
04286         /* open file */
04287         if ((tmperr = rsbac_write_open(write_item_p->name,
04288                                        file_p,
04289                                        write_item_p->device) ))
04290           {
04291             if(tmperr != -RSBAC_ENOTWRITABLE)
04292               {
04293                 rsbac_printk(KERN_WARNING
04294                        "rsbac_list_write_lol_buffers(): opening file %s on device %02u:%02u failed with error %i!\n",
04295                        write_item_p->name,
04296                        RSBAC_MAJOR(write_item_p->device),
04297                        RSBAC_MINOR(write_item_p->device),
04298                        tmperr);
04299               }
04300             goto free_item;
04301           }
04302     
04303         /* OK, now we can start writing the buffer. */
04304         /* Set current user space to kernel space, because write() reads    */
04305         /* from user space */
04306         oldfs = get_fs();
04307         set_fs(KERNEL_DS);
04308     
04309         written = 0;
04310         while ((written < write_item_p->buflen) && (tmperr >= 0)) 
04311           {
04312             bytes = rsbac_min(write_item_p->buflen - written, RSBAC_MAX_WRITE_CHUNK);
04313             tmperr = file_p->f_op->write(file_p,
04314                                       write_item_p->buf + written,
04315                                       bytes,
04316                                       &file_p->f_pos);
04317             if(tmperr > 0)
04318               {
04319                 written += tmperr;
04320               }
04321           }
04322         if (tmperr < 0)
04323           {
04324             rsbac_printk(KERN_WARNING
04325                    "rsbac_list_write_lol_buffers(): write error %i on device %02u:%02u file %s!\n",
04326                    tmperr,
04327                    RSBAC_MAJOR(write_item_p->device),
04328                    RSBAC_MINOR(write_item_p->device),
04329                    write_item_p->name);
04330             if(write_item_p->list->self == write_item_p->list)
04331               write_item_p->list->dirty = TRUE;
04332           }
04333         else
04334           count++;
04335 
04336         /* Set current user space back to user space, because write() reads */
04337         /* from user space */
04338         set_fs(oldfs);
04339     
04340     #ifdef CONFIG_RSBAC_DEBUG
04341         if (rsbac_debug_write)
04342           {
04343             rsbac_printk(KERN_DEBUG "rsbac_list_write_lol_buffers(): %lu bytes written.\n",
04344                    written);
04345           }
04346     #endif
04347         /* End of write access */
04348         rsbac_write_close(file_p);
04349 
04350 free_item:
04351         if(need_lock)
04352           unlock_kernel();
04353         /* free buffer */
04354         rsbac_vkfree(write_item_p->buf, write_item_p->vmalloc_used);
04355         next_item_p = write_item_p->next;
04356         rsbac_kfree(write_item_p);
04357         write_item_p = next_item_p;
04358       }
04359     /* Ready. */
04360     rsbac_kfree(file_p);
04361     return count;
04362   }
04363 #endif /* ifndef CONFIG_RSBAC_NO_WRITE */
04364 
04365 
04366 /************************************************* */
04367 /*           PROC support                          */
04368 /************************************************* */
04369 
04370 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
04371 static int
04372 lists_proc_info(char *buffer, char **start, off_t offset, int length)
04373 {
04374   int len = 0;
04375   off_t pos   = 0;
04376   off_t begin = 0;
04377 
04378   union rsbac_target_id_t            rsbac_target_id;
04379   union rsbac_attribute_value_t      rsbac_attribute_value;
04380   struct rsbac_list_reg_item_t     * item_p;
04381   struct rsbac_list_lol_reg_item_t * lol_item_p;
04382          u_long                      flags;
04383 
04384   if (!rsbac_is_initialized())
04385     return (-ENOSYS);
04386 
04387 #ifdef CONFIG_RSBAC_DEBUG
04388   if (rsbac_debug_aef)
04389     {
04390       rsbac_printk(KERN_DEBUG "lists_proc_info(): calling ADF\n");
04391     }
04392 #endif
04393   rsbac_target_id.scd = ST_rsbac;
04394   rsbac_attribute_value.dummy = 0;
04395   if (!rsbac_adf_request(R_GET_STATUS_DATA,
04396                          current->pid,
04397                          T_SCD,
04398                          rsbac_target_id,
04399                          A_none,
04400                          rsbac_attribute_value))
04401     {
04402       return -EPERM;
04403     }
04404 
04405   len += sprintf(buffer, "Generic Lists Status\n--------------------\n");
04406 #ifdef CONFIG_RSBAC_LIST_TRANS
04407   if(rsbac_list_count(ta_handle) > 0)
04408     {
04409       int list_count;
04410       rsbac_list_ta_number_t * desc_array;
04411       struct rsbac_list_ta_data_t data;
04412 
04413       len += sprintf(buffer+len, "Transactions active:\n\n");
04414       pos = begin + len;
04415       if (pos < offset)
04416         {
04417           len = 0;
04418           begin = pos;
04419         }
04420       if (pos > offset+length)
04421         goto out;
04422 
04423       list_count = rsbac_list_get_all_desc(ta_handle, (void **) &desc_array);
04424       if(list_count > 0)
04425         {
04426           int i;
04427           rsbac_time_t now = RSBAC_CURRENT_TIME;
04428 
04429           for(i=0; i<list_count; i++)
04430             {
04431               if(!rsbac_list_get_data(ta_handle, &desc_array[i], &data))
04432                 {
04433                   len += sprintf(buffer+len, "%u (ttl %is)\n",
04434                                  desc_array[i], data.timeout - now);
04435                   pos = begin + len;
04436                   if (pos < offset)
04437                     {
04438                       len = 0;
04439                       begin = pos;
04440                     }
04441                   if (pos > offset+length)
04442                     goto out;
04443                 }
04444             }
04445           rsbac_vfree(desc_array);
04446         }
04447 
04448       len += sprintf(buffer+len, "\nLists in Transaction\n--------------------\nName\t\tdevice\tta\t     count\n");
04449       pos = begin + len;
04450       if (pos < offset)
04451         {
04452           len = 0;
04453           begin = pos;
04454         }
04455       if (pos > offset+length)
04456         goto out;
04457 
04458       list_count = 0;
04459       rsbac_read_lock(&reg_head.lock, &flags);
04460       item_p=reg_head.head;
04461       while(item_p)
04462         {
04463           if(item_p->ta_copied)
04464             {
04465               len += sprintf(buffer + len, "%-16s%02u:%02u\t%10u\t%u\n",
04466                              item_p->name,
04467                              RSBAC_MAJOR(item_p->device), RSBAC_MINOR(item_p->device),
04468                              item_p->ta_copied,
04469                              item_p->ta_count);
04470               pos = begin + len;
04471               if (pos < offset)
04472                 {
04473                   len = 0;
04474                   begin = pos;
04475                 }
04476               if (pos > offset+length)
04477                 {
04478                   rsbac_read_unlock(&reg_head.lock, &flags);
04479                   goto out;
04480                 }
04481               list_count++;
04482             }
04483           item_p = item_p->next;
04484         }
04485       rsbac_read_unlock(&reg_head.lock, &flags);
04486 
04487       len += sprintf(buffer + len, "\n %u lists in transaction.\n\n",
04488                      list_count);
04489       pos = begin + len;
04490       if (pos < offset)
04491         {
04492           len = 0;
04493           begin = pos;
04494         }
04495       if (pos > offset+length)
04496         goto out;
04497 
04498       len += sprintf(buffer+len, "Lists of Lists in Transaction\n-----------------------------\nName\t\tdevice\tta\t     count\n");
04499       pos = begin + len;
04500       if (pos < offset)
04501         {
04502           len = 0;
04503           begin = pos;
04504         }
04505       if (pos > offset+length)
04506         goto out;
04507 
04508       list_count = 0;
04509       rsbac_read_lock(&lol_reg_head.lock, &flags);
04510       lol_item_p=lol_reg_head.head;
04511       while(lol_item_p)
04512         {
04513           if(lol_item_p->ta_copied)
04514             {
04515               len += sprintf(buffer + len, "%-16s%02u:%02u\t%10u\t%u\n",
04516                              lol_item_p->name,
04517                              RSBAC_MAJOR(lol_item_p->device), RSBAC_MINOR(lol_item_p->device),
04518                              lol_item_p->ta_copied,
04519                              lol_item_p->ta_count);
04520               pos = begin + len;
04521               if (pos < offset)
04522                 {
04523                   len = 0;
04524                   begin = pos;
04525                 }
04526               if (pos > offset+length)
04527                 {
04528                   rsbac_read_unlock(&lol_reg_head.lock, &flags);
04529                   goto out;
04530                 }
04531               list_count++;
04532             }
04533           lol_item_p = lol_item_p->next;
04534         }
04535       rsbac_read_unlock(&lol_reg_head.lock, &flags);
04536 
04537       len += sprintf(buffer + len, "\n %u lists of lists in transaction.\n\n\n",
04538                      list_count);
04539       pos = begin + len;
04540       if (pos < offset)
04541         {
04542           len = 0;
04543           begin = pos;
04544         }
04545       if (pos > offset+length)
04546         goto out;
04547     }
04548   else
04549     len += sprintf(buffer+len, "No active transaction\n\n");
04550   pos = begin + len;
04551   if (pos < offset)
04552     {
04553       len = 0;
04554       begin = pos;
04555     }
04556   if (pos > offset+length)
04557     goto out;
04558 #endif
04559 
04560   len += sprintf(buffer+len, "Registered Generic Lists\n------------------------\nName\t\tdevice\tcount\tdesc\tdata\tpersist\tnowrite\tflags\tdirty\n");
04561   pos = begin + len;
04562   if (pos < offset)
04563     {
04564       len = 0;
04565       begin = pos;
04566     }
04567   if (pos > offset+length)
04568     goto out;
04569 
04570   rsbac_read_lock(&reg_head.lock, &flags);
04571   item_p=reg_head.head;
04572   while(item_p)
04573     {
04574       len += sprintf(buffer + len, "%-16s%02u:%02u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\n",
04575                      item_p->name,
04576                      RSBAC_MAJOR(item_p->device), RSBAC_MINOR(item_p->device),
04577                      item_p->count,
04578                      item_p->info.desc_size,
04579                      item_p->info.data_size,
04580                      item_p->flags & RSBAC_LIST_PERSIST,
04581                      item_p->no_write,
04582                      item_p->flags,
04583                      item_p->dirty & (item_p->flags & RSBAC_LIST_PERSIST));
04584       pos = begin + len;
04585       if (pos < offset)
04586         {
04587           len = 0;
04588           begin = pos;
04589         }
04590       if (pos > offset+length)
04591         {
04592           rsbac_read_unlock(&reg_head.lock, &flags);
04593           goto out;
04594         }
04595       item_p = item_p->next;
04596     }
04597   rsbac_read_unlock(&reg_head.lock, &flags);
04598 
04599   len += sprintf(buffer + len, "\n %u lists registered.\n\n",
04600                  reg_head.count);
04601   pos = begin + len;
04602   if (pos < offset)
04603     {
04604       len = 0;
04605       begin = pos;
04606     }
04607   if (pos > offset+length)
04608     goto out;
04609 
04610   len += sprintf(buffer + len, "Registered Generic Lists of Lists\n---------------------------------\nName\t\tdevice\tcount\tdesc\tdata\tpersist\tnowrite\tflags\tdirty\n");
04611   pos = begin + len;
04612   if (pos < offset)
04613     {
04614       len = 0;
04615       begin = pos;
04616     }
04617   if (pos > offset+length)
04618     goto out;
04619 
04620   rsbac_read_lock(&lol_reg_head.lock, &flags);
04621   lol_item_p=lol_reg_head.head;
04622   while(lol_item_p)
04623     {
04624       len += sprintf(buffer + len, "%-16s%02u:%02u\t%u\t%u+%u\t%u+%u\t%u\t%u\t%u\t%u\n",
04625                      lol_item_p->name,
04626                      RSBAC_MAJOR(lol_item_p->device), RSBAC_MINOR(lol_item_p->device),
04627                      lol_item_p->count,
04628                      lol_item_p->info.desc_size,
04629                      lol_item_p->info.subdesc_size,
04630                      lol_item_p->info.data_size,
04631                      lol_item_p->info.subdata_size,
04632                      lol_item_p->flags & RSBAC_LIST_PERSIST,
04633                      lol_item_p->no_write,
04634                      lol_item_p->flags,
04635                      lol_item_p->dirty & (lol_item_p->flags & RSBAC_LIST_PERSIST));
04636       pos = begin + len;
04637       if (pos < offset)
04638         {
04639           len = 0;
04640           begin = pos;
04641         }
04642       if (pos > offset+length)
04643         {
04644           rsbac_read_unlock(&lol_reg_head.lock, &flags);
04645           goto out;
04646         }
04647       lol_item_p = lol_item_p->next;
04648     }
04649   rsbac_read_unlock(&lol_reg_head.lock, &flags);
04650 
04651   len += sprintf(buffer + len, "\n %u lists of lists registered.\n",
04652                  lol_reg_head.count);
04653   pos = begin + len;
04654   if (pos < offset)
04655     {
04656       len = 0;
04657       begin = pos;
04658     }
04659   if (pos > offset+length)
04660     goto out;
04661 
04662 out:
04663   *start = buffer + (offset - begin);
04664   len -= (offset - begin);
04665   
04666   if (len > length)
04667     len = length;
04668   return len;
04669 }
04670 
04671 #if defined(CONFIG_RSBAC_LIST_REPL)
04672 static int
04673 repl_lists_proc_info(char *buffer, char **start, off_t offset, int length)
04674 {
04675   int len = 0;
04676   off_t pos   = 0;
04677   off_t begin = 0;
04678 
04679   union rsbac_target_id_t            rsbac_target_id;
04680   union rsbac_attribute_value_t      rsbac_attribute_value;
04681   struct rsbac_list_reg_item_t     * item_p;
04682   struct rsbac_list_lol_reg_item_t * lol_item_p;
04683          u_long                      flags;
04684 
04685   if (!rsbac_is_initialized())
04686     return (-ENOSYS);
04687 
04688 #ifdef CONFIG_RSBAC_DEBUG
04689   if (rsbac_debug_aef)
04690     {
04691       rsbac_printk(KERN_DEBUG "repl_lists_proc_info(): calling ADF\n");
04692     }
04693 #endif
04694   rsbac_target_id.scd = ST_rsbac;
04695   rsbac_attribute_value.dummy = 0;
04696   if (!rsbac_adf_request(R_GET_STATUS_DATA,
04697                          current->pid,
04698                          T_SCD,
04699                          rsbac_target_id,
04700                          A_none,
04701                          rsbac_attribute_value))
04702     {
04703       return -EPERM;
04704     }
04705 
04706   len += sprintf(buffer, "List Replication Status\n--------------------\n");
04707   len += sprintf(buffer, "Last Replication at: %u:%u",
04708                  repl_last.sec, repl_last.nsec);
04709 
04710   len += sprintf(buffer+len, "Lists\n-----\nName\t\tdevice\tlastchange\n");
04711   pos = begin + len;
04712   if (pos < offset)
04713     {
04714       len = 0;
04715       begin = pos;
04716     }
04717   if (pos > offset+length)
04718     goto out;
04719 
04720   rsbac_read_lock(&reg_head.lock, &flags);
04721   item_p=reg_head.head;
04722   while(item_p)
04723     {
04724       len += sprintf(buffer + len, "%-16s%02u:%02u\t%u:%u\n",
04725                      item_p->name,
04726                      RSBAC_MAJOR(item_p->device), RSBAC_MINOR(item_p->device),
04727                      item_p->lastchange.sec,
04728                      item_p->lastchange.nsec);
04729       pos = begin + len;
04730       if (pos < offset)
04731         {
04732           len = 0;
04733           begin = pos;
04734         }
04735       if (pos > offset+length)
04736         {
04737           rsbac_read_unlock(&reg_head.lock, &flags);
04738           goto out;
04739         }
04740       item_p = item_p->next;
04741     }
04742   rsbac_read_unlock(&reg_head.lock, &flags);
04743 
04744   len += sprintf(buffer + len, "\n %u lists registered.\n\n",
04745                  reg_head.count);
04746   pos = begin + len;
04747   if (pos < offset)
04748     {
04749       len = 0;
04750       begin = pos;
04751     }
04752   if (pos > offset+length)
04753     goto out;
04754 
04755   len += sprintf(buffer + len, "Lists of Lists\n-----------------\nName\t\tdevice\tlastchange\n");
04756   pos = begin + len;
04757   if (pos < offset)
04758     {
04759       len = 0;
04760       begin = pos;
04761     }
04762   if (pos > offset+length)
04763     goto out;
04764 
04765   rsbac_read_lock(&lol_reg_head.lock, &flags);
04766   lol_item_p=lol_reg_head.head;
04767   while(lol_item_p)
04768     {
04769       len += sprintf(buffer + len, "%-16s%02u:%02u\t%u:%u\n",
04770                      lol_item_p->name,
04771                      RSBAC_MAJOR(lol_item_p->device), RSBAC_MINOR(lol_item_p->device),
04772                      lol_item_p->lastchange.sec,
04773                      lol_item_p->lastchange.nsec);
04774       pos = begin + len;
04775       if (pos < offset)
04776         {
04777           len = 0;
04778           begin = pos;
04779         }
04780       if (pos > offset+length)
04781         {
04782           rsbac_read_unlock(&lol_reg_head.lock, &flags);
04783           goto out;
04784         }
04785       lol_item_p = lol_item_p->next;
04786     }
04787   rsbac_read_unlock(&lol_reg_head.lock, &flags);
04788 
04789   len += sprintf(buffer + len, "\n %u lists of lists registered.\n",
04790                  lol_reg_head.count);
04791   pos = begin + len;
04792   if (pos < offset)
04793     {
04794       len = 0;
04795       begin = pos;
04796     }
04797   if (pos > offset+length)
04798     goto out;
04799 
04800 out:
04801   *start = buffer + (offset - begin);
04802   len -= (offset - begin);
04803   
04804   if (len > length)
04805     len = length;
04806   return len;
04807 }
04808 #endif /* CONFIG_RSBAC_LIST_REPL */
04809 
04810 /* Generic backup generation function */
04811 static int backup_proc_read(char *page, char **start, off_t off,
04812   int count, int *eof, void *data)
04813   {
04814     int len = 0;
04815     off_t pos   = 0;
04816     off_t begin = 0;
04817 
04818     union  rsbac_target_id_t         rsbac_target_id;
04819     union  rsbac_attribute_value_t   rsbac_attribute_value;
04820     struct rsbac_list_reg_item_t   * list;
04821     struct rsbac_list_item_t       * current_p;
04822            rsbac_version_t           list_version = RSBAC_LIST_DISK_VERSION;
04823            rsbac_time_t              timestamp = RSBAC_CURRENT_TIME;
04824            u_long                    rflags, flags;
04825 
04826     if (!rsbac_is_initialized())
04827       return -ENOSYS;
04828 
04829 #ifdef CONFIG_RSBAC_DEBUG
04830     if (rsbac_debug_aef)
04831       {
04832         rsbac_printk(KERN_DEBUG "backup_proc_read(): calling ADF\n");
04833       }
04834 #endif
04835     rsbac_target_id.scd = ST_rsbac;
04836     rsbac_attribute_value.dummy = 0;
04837     if (!rsbac_adf_request(R_GET_STATUS_DATA,
04838                            current->pid,
04839                            T_SCD,
04840                            rsbac_target_id,
04841                            A_none,
04842                            rsbac_attribute_value))
04843       {
04844         return -EPERM;
04845       }
04846 
04847     rsbac_read_lock(&reg_head.lock, &rflags);
04848     list=lookup_reg(data);
04849     if(!list)
04850       {
04851         rsbac_read_unlock(&reg_head.lock, &rflags);
04852         return -ENOSYS;
04853       }
04854     /* lock list */
04855     rsbac_read_lock(&list->lock, &flags);
04856     /* copy version */
04857     memcpy(page,
04858            (char *) &list_version,
04859            sizeof(list_version));
04860     len = sizeof(list_version);
04861     /* copy version */
04862     memcpy(page+len,
04863            (char *) &timestamp,
04864            sizeof(timestamp));
04865     len += sizeof(timestamp);
04866     /* copy info */
04867     memcpy(page+len,
04868            (char *) &list->info,
04869            sizeof(list->info));
04870     len += sizeof(list->info);
04871     pos = begin + len;
04872     if (pos < off)
04873       {
04874         len = 0;
04875         begin = pos;
04876       }
04877     if (pos > off+count)
04878       {
04879         goto out;
04880       }
04881 
04882     /* copy list */
04883     current_p = list->head;
04884     while (current_p) 
04885       {
04886         memcpy(page+len,
04887                ((char *) current_p) + sizeof(*current_p),
04888                list->info.desc_size + list->info.data_size);
04889         len += list->info.desc_size + list->info.data_size;
04890         pos = begin + len;
04891         if (pos < off)
04892           {
04893             len = 0;
04894             begin = pos;
04895           }
04896         if (pos > off+count)
04897           {
04898             goto out;
04899           }
04900         current_p = current_p->next;
04901       }
04902 
04903   out:
04904     /* unprotect this list */
04905     rsbac_read_unlock(&list->lock, &flags);
04906     rsbac_read_unlock(&reg_head.lock, &rflags);
04907     if(len <= off+count)
04908       *eof=1;
04909     *start = page + (off - begin);
04910     len -= (off - begin);
04911   
04912     if (len > count)
04913       len = count;
04914     return len;
04915   }
04916 
04917 /* Generic lists of lists backup generation function */
04918 static int lol_backup_proc_read(char *page, char **start, off_t off,
04919   int count, int *eof, void *data)
04920   {
04921     int len = 0;
04922     off_t pos   = 0;
04923     off_t begin = 0;
04924 
04925     union  rsbac_target_id_t           rsbac_target_id;
04926     union  rsbac_attribute_value_t     rsbac_attribute_value;
04927     struct rsbac_list_lol_reg_item_t * list;
04928     struct rsbac_list_lol_item_t     * current_p;
04929     struct rsbac_list_item_t         * sub_p;
04930            rsbac_version_t             list_version = RSBAC_LIST_DISK_VERSION;
04931            rsbac_time_t                timestamp = RSBAC_CURRENT_TIME;
04932            u_long                      rflags, flags;
04933 
04934     if (!rsbac_is_initialized())
04935       return (-ENOSYS);
04936 
04937 #ifdef CONFIG_RSBAC_DEBUG
04938     if (rsbac_debug_aef)
04939       {
04940         rsbac_printk(KERN_DEBUG "lol_backup_proc_read(): calling ADF\n");
04941       }
04942 #endif
04943     rsbac_target_id.scd = ST_rsbac;
04944     rsbac_attribute_value.dummy = 0;
04945     if (!rsbac_adf_request(R_GET_STATUS_DATA,
04946                            current->pid,
04947                            T_SCD,
04948                            rsbac_target_id,
04949                            A_none,
04950                            rsbac_attribute_value))
04951       {
04952         return -EPERM;
04953       }
04954 
04955     rsbac_read_lock(&lol_reg_head.lock, &rflags);
04956     list=lookup_lol_reg(data);
04957     if(!list)
04958       {
04959         rsbac_read_unlock(&lol_reg_head.lock, &rflags);
04960         return -ENOSYS;
04961       }
04962     /* lock list */
04963     rsbac_read_lock(&list->lock, &flags);
04964     /* copy version */
04965     memcpy(page,
04966            (char *) &list_version,
04967            sizeof(list_version));
04968     len = sizeof(list_version);
04969     /* copy version */
04970     memcpy(page+len,
04971            (char *) &timestamp,
04972            sizeof(timestamp));
04973     len += sizeof(timestamp);
04974     /* copy info */
04975     memcpy(page+len,
04976            (char *) &list->info,
04977            sizeof(list->info));
04978     len += sizeof(list->info);
04979     pos = begin + len;
04980     if (pos < off)
04981       {
04982         len = 0;
04983         begin = pos;
04984       }
04985     if (pos > off+count)
04986       {
04987         goto out;
04988       }
04989 
04990     /* copy list */
04991     current_p = list->head;
04992     while (current_p) 
04993       {
04994         memcpy(page+len,
04995                ((char *) current_p) + sizeof(*current_p),
04996                list->info.desc_size + list->info.data_size);
04997         len += list->info.desc_size + list->info.data_size;
04998         memcpy(page+len,
04999                &current_p->count,
05000                sizeof(current_p->count));
05001         len += sizeof(current_p->count);
05002         pos = begin + len;
05003         if (pos < off)
05004           {
05005             len = 0;
05006             begin = pos;
05007           }
05008         if (pos > off+count)
05009           {
05010             goto out;
05011           }
05012         /* copy sublist */
05013         sub_p = current_p->head;
05014         while (sub_p)
05015           {
05016             memcpy(page+len,
05017                    ((char *) sub_p) + sizeof(*sub_p),
05018                    list->info.subdesc_size + list->info.subdata_size);
05019             len += list->info.subdesc_size + list->info.subdata_size;
05020             pos = begin + len;
05021             if (pos < off)
05022               {
05023                 len = 0;
05024                 begin = pos;
05025               }
05026             if (pos > off+count)
05027               {
05028                 goto out;
05029               }
05030             sub_p = sub_p->next;
05031           }
05032         current_p = current_p->next;
05033       }
05034 
05035   out:
05036     /* unprotect this list */
05037     rsbac_read_unlock(&list->lock, &flags);
05038     rsbac_read_unlock(&lol_reg_head.lock, &rflags);
05039     if(len <= off+count)
05040       *eof=1;
05041     *start = page + (off - begin);
05042     len -= (off - begin);
05043   
05044     if (len > count)
05045       len = count;
05046     return len;
05047   }
05048 #endif /* PROC */
05049 
05050 
05051 /********************/
05052 /* Init and general */
05053 /********************/
05054 
05055 int rsbac_list_compare_u32(void * desc1, void * desc2)
05056   {
05057     if( *((__u32*) desc1) < *((__u32*) desc2))
05058       return -1;
05059     return( *((__u32*) desc1) != *((__u32*) desc2));
05060   }
05061 
05062 #ifdef CONFIG_RSBAC_INIT_DELAY
05063 int rsbac_list_init(void)
05064 #else
05065 int __init rsbac_list_init(void)
05066 #endif
05067   {
05068     #ifdef CONFIG_RSBAC_LIST_TRANS
05069     int err;
05070     struct rsbac_list_info_t * list_info_p;
05071     #endif
05072 
05073     reg_head.head  = NULL;
05074     reg_head.tail  = NULL;
05075     reg_head.curr  = NULL;
05076     reg_head.lock  = RW_LOCK_UNLOCKED;
05077     reg_head.count = 0;
05078 
05079     lol_reg_head.head  = NULL;
05080     lol_reg_head.tail  = NULL;
05081     lol_reg_head.curr  = NULL;
05082     lol_reg_head.lock  = RW_LOCK_UNLOCKED;
05083     lol_reg_head.count = 0;
05084 
05085     list_initialized = TRUE;
05086 
05087     #ifdef CONFIG_RSBAC_LIST_REPL
05088     repl_last.sec = 0;
05089     repl_last.nsec = 0;
05090     #endif
05091 
05092     /* init proc entry */
05093     #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
05094     {
05095       struct proc_dir_entry * tmp_entry_p;
05096 
05097       tmp_entry_p = create_proc_entry(RSBAC_LIST_PROC_NAME,
05098                                       S_IFREG | S_IRUGO,
05099                                       proc_rsbac_root_p);
05100       if(tmp_entry_p)
05101         {
05102           tmp_entry_p->get_info = lists_proc_info;
05103         }
05104       #if defined(CONFIG_RSBAC_LIST_REPL)
05105       tmp_entry_p = create_proc_entry(RSBAC_LIST_REPL_PROC_NAME,
05106                                       S_IFREG | S_IRUGO,
05107                                       proc_rsbac_root_p);
05108       if(tmp_entry_p)
05109         {
05110           tmp_entry_p->get_info = repl_lists_proc_info;
05111         }
05112       #endif
05113     }
05114     #endif
05115 
05116     #ifdef CONFIG_RSBAC_LIST_TRANS
05117     rsbac_printk(KERN_INFO
05118                  "rsbac_list_init(): Registering transaction list.\n");
05119     list_info_p = kmalloc(sizeof(*list_info_p), GFP_KERNEL);
05120     if(!list_info_p)
05121       {
05122         return -ENOMEM;
05123       }
05124     list_info_p->version = 1;
05125     list_info_p->key = RSBAC_LIST_TA_KEY;
05126     list_info_p->desc_size = sizeof(rsbac_list_ta_number_t);
05127     list_info_p->data_size = sizeof(struct rsbac_list_ta_data_t);
05128     list_info_p->max_age = 0;
05129     err = rsbac_list_register(RSBAC_LIST_VERSION,
05130                               (void **) &ta_handle,
05131                               list_info_p,
05132                               0,
05133                               rsbac_list_compare_u32,
05134                               NULL,
05135                               NULL,
05136                               "transactions",
05137                               RSBAC_AUTO_DEV);
05138     if(err)
05139       {
05140         char * tmp = kmalloc(RSBAC_MAXNAMELEN, GFP_KERNEL);
05141 
05142         if(tmp)
05143           {
05144             rsbac_printk(KERN_WARNING
05145                    "rsbac_list_init(): Registering transaction list failed with error %s\n",
05146                    get_error_name(tmp, err));
05147             kfree(tmp);
05148           }
05149       }
05150     kfree(list_info_p);
05151     #endif
05152 
05153     #ifdef CONFIG_RSBAC_LIST_REPL
05154     rsbac_printk(KERN_INFO
05155                  "rsbac_list_init(): Registering replication partner list.\n");
05156     list_info_p = kmalloc(sizeof(*list_info_p), GFP_KERNEL);
05157     if(!list_info_p)
05158       {
05159         return -ENOMEM;
05160       }
05161     list_info_p->version = RSBAC_LIST_REPL_PARTNER_VERSION;
05162     list_info_p->key = RSBAC_LIST_REPL_PARTNER_KEY;
05163     list_info_p->desc_size = sizeof(rsbac_list_repl_partner_number_t);
05164     list_info_p->data_size = sizeof(struct rsbac_list_repl_partner_entry_t);
05165     list_info_p->max_age = 0;
05166     err = rsbac_list_register(RSBAC_LIST_VERSION,
05167                               (void **) &repl_partner_handle,
05168                               list_info_p,
05169                               RSBAC_LIST_PERSIST,
05170                               NULL,
05171                               NULL,
05172                               NULL,
05173                               RSBAC_LIST_REPL_PARTNER_FILENAME,
05174                               RSBAC_AUTO_DEV);
05175     if(err)
05176       {
05177         char * tmp = kmalloc(RSBAC_MAXNAMELEN, GFP_KERNEL);
05178 
05179         if(tmp)
05180           {
05181             rsbac_printk(KERN_WARNING
05182                    "rsbac_list_init(): Registering replication partner list failed with error %s\n",
05183                    get_error_name(tmp, err));
05184             kfree(tmp);
05185           }
05186       }
05187     kfree(list_info_p);
05188     #endif
05189 
05190     return 0;
05191   }
05192 
05193 int rsbac_list_mount(kdev_t kdev)
05194   {
05195     return 0;
05196   }
05197 
05198 int rsbac_list_umount(kdev_t kdev)
05199   {
05200     return 0;
05201   }
05202 
05203 #ifdef CONFIG_RSBAC_AUTO_WRITE
05204 int rsbac_write_lists(rsbac_boolean_t need_lock)
05205   {
05206     int count = 0;
05207     int subcount = 0;
05208     int error = 0;
05209     struct rsbac_list_reg_item_t       * item_p;
05210     struct rsbac_list_lol_reg_item_t   * lol_item_p;
05211            u_long                        lock_flags;
05212     struct rsbac_list_write_head_t       write_head;
05213     struct rsbac_list_write_item_t     * write_item_p;
05214     struct rsbac_list_lol_write_head_t   write_lol_head;
05215     struct rsbac_list_lol_write_item_t * write_lol_item_p;
05216 
05217 /*
05218 #ifdef CONFIG_RSBAC_DEBUG
05219     if(rsbac_debug_lists)
05220       rsbac_printk(KERN_DEBUG "rsbac_write_lists() called.\n");
05221 #endif
05222 */
05223     if(!list_initialized)
05224       return -RSBAC_ENOTINITIALIZED;
05225 
05226 #ifdef CONFIG_RSBAC_LIST_TRANS
05227     if(rsbac_list_count(ta_handle) > 0)
05228       {
05229         int list_count;
05230         rsbac_list_ta_number_t * desc_array;
05231         struct rsbac_list_ta_data_t data;
05232 
05233         list_count = rsbac_list_get_all_desc(ta_handle, (void **) &desc_array);
05234         if(list_count > 0)
05235           {
05236             int i;
05237             rsbac_time_t now = RSBAC_CURRENT_TIME;
05238 
05239             for(i=0; i<list_count; i++)
05240               {
05241                 if(!rsbac_list_get_data(ta_handle, &desc_array[i], &data))
05242                   {
05243                     if(data.timeout < now)
05244                       {
05245                         rsbac_printk(KERN_WARNING
05246                                      "rsbac_write_lists(): transaction %u timed out, forcing forget\n",
05247                                      desc_array[i]);
05248                         do_forget(desc_array[i]);
05249                       }
05250                   }
05251               }
05252             rsbac_vfree(desc_array);
05253           }
05254       }
05255 #endif
05256 
05257     /* Init buffer list */
05258     write_head.head=NULL;
05259     write_head.tail=NULL;
05260     write_head.total=0;
05261     write_head.count=0;
05262 
05263     rsbac_read_lock(&reg_head.lock, &lock_flags);
05264     item_p=reg_head.head;
05265     while(item_p)
05266       {
05267         if(   (item_p->flags & RSBAC_LIST_PERSIST)
05268            && item_p->dirty
05269            && !item_p->no_write
05270           )
05271           {
05272             item_p->dirty = FALSE;
05273             /* list locking is done in fill_buffer */
05274             error = fill_buffer(item_p, &write_item_p);
05275             if(!error)
05276               {
05277                 if(!write_head.head)
05278                   {
05279                     write_head.head = write_item_p;
05280                     write_head.tail = write_item_p;
05281                     write_head.total = write_item_p->buflen;
05282                     write_head.count = 1;
05283                   }
05284                 else
05285                   {
05286                     write_head.tail->next = write_item_p;
05287                     write_item_p->prev = write_head.tail;
05288                     write_head.tail = write_item_p;
05289                     write_head.total += write_item_p->buflen;
05290                     write_head.count++;
05291                   }
05292               }
05293             else
05294               {
05295                 if(   (error != -RSBAC_ENOTWRITABLE)
05296                    && (error != -RSBAC_ENOMEM)
05297                   )
05298                   {
05299                     rsbac_printk(KERN_WARNING
05300                            "rsbac_write_lists(): fill_buffer() for list %s returned error %i\n",
05301                            item_p->name, error);
05302                   }
05303               }
05304           }
05305         item_p=item_p->next;
05306       }
05307     rsbac_read_unlock(&reg_head.lock, &lock_flags);
05308 
05309 #ifdef CONFIG_RSBAC_DEBUG
05310     if(   rsbac_debug_write
05311        && (write_head.count > 0)
05312       )
05313       {
05314         rsbac_printk(KERN_DEBUG
05315                "rsbac_write_lists(): %u lists copied to buffers, total of %lu bytes\n",
05316                write_head.count,
05317                write_head.total);
05318       }
05319 #endif
05320 
05321     /* write all buffers */
05322     if(write_head.count)
05323       {
05324         count = rsbac_list_write_buffers(write_head, need_lock);
05325 #ifdef CONFIG_RSBAC_DEBUG
05326         if(rsbac_debug_write)
05327           {
05328             rsbac_printk(KERN_DEBUG
05329                    "rsbac_write_lists(): %u lists written to disk\n",
05330                    count);
05331           }
05332 #endif
05333       }
05334 
05335     /* LOL */
05336     /* Init buffer list */
05337     write_lol_head.head=NULL;
05338     write_lol_head.tail=NULL;
05339     write_lol_head.total=0;
05340     write_lol_head.count=0;
05341 
05342     rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
05343     lol_item_p=lol_reg_head.head;
05344     while(lol_item_p)
05345       {
05346         if(   (lol_item_p->flags & RSBAC_LIST_PERSIST)
05347            && lol_item_p->dirty
05348            && !lol_item_p->no_write
05349           )
05350           {
05351             lol_item_p->dirty = FALSE;
05352             /* list locking is done in fill_buffer */
05353             error = fill_lol_buffer(lol_item_p, &write_lol_item_p);
05354             if(!error)
05355               {
05356                 if(!write_lol_head.head)
05357                   {
05358                     write_lol_head.head = write_lol_item_p;
05359                     write_lol_head.tail = write_lol_item_p;
05360                     write_lol_head.total = write_lol_item_p->buflen;
05361                     write_lol_head.count = 1;
05362                   }
05363                 else
05364                   {
05365                     write_lol_head.tail->next = write_lol_item_p;
05366                     write_lol_item_p->prev = write_lol_head.tail;
05367                     write_lol_head.tail = write_lol_item_p;
05368                     write_lol_head.total += write_lol_item_p->buflen;
05369                     write_lol_head.count++;
05370                   }
05371               }
05372             else
05373               {
05374                 if(   (error != -RSBAC_ENOTWRITABLE)
05375                    && (error != -RSBAC_ENOMEM)
05376                   )
05377                   {
05378                     rsbac_printk(KERN_WARNING
05379                            "rsbac_write_lists(): fill_lol_buffer() for list %s returned error %i\n",
05380                            lol_item_p->name, error);
05381                   }
05382               }
05383           }
05384         lol_item_p=lol_item_p->next;
05385       }
05386     rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
05387 
05388 #ifdef CONFIG_RSBAC_DEBUG
05389     if(   rsbac_debug_write
05390        && (write_lol_head.count > 0)
05391       )
05392       {
05393         rsbac_printk(KERN_DEBUG
05394                "rsbac_write_lists(): %u lists of lists copied to buffers, total of %lu bytes\n",
05395                write_lol_head.count,
05396                write_lol_head.total);
05397       }
05398 #endif
05399 
05400     /* write all buffers */
05401     if(write_lol_head.count)
05402       {
05403         subcount = rsbac_list_write_lol_buffers(write_lol_head, need_lock);
05404         count += subcount;
05405 #ifdef CONFIG_RSBAC_DEBUG
05406         if(rsbac_debug_write)
05407           {
05408             rsbac_printk(KERN_DEBUG
05409                    "rsbac_write_lists(): %u lists of lists written to disk\n",
05410                    subcount);
05411           }
05412 #endif
05413       }
05414 
05415 #ifdef CONFIG_RSBAC_DEBUG
05416     if (rsbac_debug_write)
05417       {
05418         rsbac_printk(KERN_DEBUG "rsbac_write_lists(): %u lists with a total of %lu bytes written.\n",
05419                count, write_head.total + write_lol_head.total);
05420       }
05421 #endif
05422     return count;
05423   }
05424 #endif /* CONFIG_RSBAC_AUTO_WRITE */
05425 
05426 /* Status checking */
05427 int rsbac_check_lists(int correct)
05428   {
05429     struct rsbac_list_reg_item_t     * list;
05430     struct rsbac_list_lol_reg_item_t * lol_list;
05431     struct rsbac_list_item_t         * item_p;
05432     struct rsbac_list_item_t         * next_item_p;
05433     struct rsbac_list_lol_item_t     * lol_item_p;
05434     struct rsbac_list_lol_item_t     * next_lol_item_p;
05435     struct rsbac_list_item_t         * lol_subitem_p;
05436     struct rsbac_list_item_t         * next_lol_subitem_p;
05437            u_long                      lock_flags, rlock_flags;
05438            u_long                      tmp_count;
05439            u_long                      tmp_subcount;
05440            u_long                      subitem_count;
05441            u_long                      dirty = 0;
05442 
05443 #ifdef CONFIG_RSBAC_DEBUG
05444     if(rsbac_debug_lists)
05445       {
05446         rsbac_printk(KERN_DEBUG "rsbac_check_lists() called.\n");
05447       }
05448 #endif
05449     if(!list_initialized)
05450       return -RSBAC_ENOTINITIALIZED;
05451     rsbac_read_lock(&reg_head.lock, &rlock_flags);
05452     list = reg_head.head;
05453     while(list)
05454       {
05455         /* check list */
05456         rsbac_write_lock(&list->lock, &lock_flags);
05457         tmp_count = 0;
05458         item_p = list->head;
05459         while(item_p)
05460           {
05461             if(   (   item_p->max_age
05462                    && (item_p->max_age <= RSBAC_CURRENT_TIME)
05463                   )
05464                || (   list->def_data
05465                    && !memcmp(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
05466                               list->def_data,
05467                               list->info.data_size)
05468                   )
05469               )
05470               {
05471                 next_item_p = item_p->next;
05472                 do_remove_item(list, item_p);
05473                 item_p = next_item_p;
05474               }
05475             else
05476               {
05477                 tmp_count++;
05478                 item_p = item_p->next;
05479               }
05480           }
05481         if(tmp_count != list->count)
05482           {
05483             if(correct)
05484               {
05485                 rsbac_printk(KERN_WARNING
05486                        "rsbac_check_lists(): correcting count mismatch for list %s on device %02u:%02u - was %u, counted %lu!\n",
05487                        list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count);
05488                 list->count = tmp_count;
05489               }
05490             else
05491               {
05492                 rsbac_printk(KERN_WARNING
05493                        "rsbac_check_lists(): count mismatch for list %s on device %02u:%02u - is %u, counted %lu!\n",
05494                        list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count);
05495               }
05496           }
05497         rsbac_write_unlock(&list->lock, &lock_flags);
05498         if(list->dirty && (list->flags & RSBAC_LIST_PERSIST))
05499           {
05500             dirty++;
05501 #ifdef CONFIG_RSBAC_DEBUG
05502             if(rsbac_debug_lists)
05503               {
05504                 rsbac_printk(KERN_DEBUG
05505                        "rsbac_check_lists(): %s on %02u:%02u has %u items (list is dirty)\n",
05506                        list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count);
05507               }
05508 #endif
05509           }
05510 #ifdef CONFIG_RSBAC_DEBUG
05511         else
05512           {
05513             if(rsbac_debug_lists)
05514               {
05515                 rsbac_printk(KERN_DEBUG
05516                        "rsbac_check_lists(): %s on %02u:%02u has %u items\n",
05517                        list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count);
05518               }
05519           }
05520 #endif
05521         list = list->next;
05522       }
05523     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
05524 
05525     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
05526     lol_list = lol_reg_head.head;
05527     while(lol_list)
05528       {
05529         /* check list */
05530         rsbac_write_lock(&lol_list->lock, &lock_flags);
05531         tmp_count = 0;
05532         subitem_count = 0;
05533         lol_item_p = lol_list->head;
05534         while(lol_item_p)
05535           {
05536             if(   (   lol_item_p->max_age
05537                    && (lol_item_p->max_age <= RSBAC_CURRENT_TIME)
05538                   )
05539                || (   lol_list->def_data
05540                    && !lol_item_p->count
05541                    && !memcmp(((char *) lol_item_p) + sizeof(*lol_item_p) + lol_list->info.desc_size,
05542                               lol_list->def_data,
05543                               lol_list->info.data_size)
05544                   )
05545                || (   !lol_list->info.data_size
05546                    && (lol_list->flags & RSBAC_LIST_DEF_DATA)
05547                    && !lol_item_p->count
05548                   )
05549               )
05550               {
05551                 next_lol_item_p = lol_item_p->next;
05552                 do_remove_lol_item(lol_list, lol_item_p);
05553                 lol_item_p = next_lol_item_p;
05554               }
05555             else
05556               {
05557                 tmp_count++;
05558                 tmp_subcount = 0;
05559                 lol_subitem_p = lol_item_p->head;
05560                 while(lol_subitem_p)
05561                   {
05562                     if(   (   lol_subitem_p->max_age
05563                            && (lol_subitem_p->max_age <= RSBAC_CURRENT_TIME)
05564                           )
05565                        || (   lol_list->def_subdata
05566                            && !memcmp(((char *) lol_subitem_p) + sizeof(*lol_subitem_p) + lol_list->info.subdesc_size,
05567                                       lol_list->def_subdata,
05568                                       lol_list->info.subdata_size)
05569                           )
05570                       )
05571                       {
05572                         next_lol_subitem_p = lol_subitem_p->next;
05573                         do_remove_lol_subitem(lol_item_p, lol_subitem_p);
05574                         lol_subitem_p = next_lol_subitem_p;
05575                       }
05576                     else
05577                       {
05578                         tmp_subcount++;
05579                         lol_subitem_p = lol_subitem_p->next;
05580                       }
05581                   }
05582                 if(tmp_subcount != lol_item_p->count)
05583                   {
05584                     if(correct)
05585                       {
05586                         rsbac_printk(KERN_WARNING
05587                                "rsbac_check_lists(): correcting count mismatch for list of lists %s sublist on %02u:%02u - was %lu, counted %lu!\n",
05588                                lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount);
05589                         lol_item_p->count = tmp_subcount;
05590                       }
05591                     else
05592                       {
05593                         rsbac_printk(KERN_WARNING
05594                                "rsbac_check_lists(): count mismatch for list of lists %s sublist on %02u:%02u - is %lu, counted %lu!\n",
05595                                lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount);
05596                       }
05597                   }
05598                 subitem_count += lol_item_p->count;
05599                 lol_item_p = lol_item_p->next;
05600               }
05601           }
05602         if(tmp_count != lol_list->count)
05603           {
05604             if(correct)
05605               {
05606                 rsbac_printk(KERN_WARNING
05607                        "rsbac_check_lists(): correcting count mismatch for list of lists %s on %02u:%02u - was %u, counted %lu!\n",
05608                        lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count);
05609                 lol_list->count = tmp_count;
05610               }
05611             else
05612               {
05613                 rsbac_printk(KERN_WARNING
05614                        "rsbac_check_lists(): count mismatch for list of lists %s on %02u:%02u - is %u, counted %lu!\n",
05615                        lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count);
05616               }
05617           }
05618         rsbac_write_unlock(&lol_list->lock, &lock_flags);
05619         if(lol_list->dirty && (lol_list->flags & RSBAC_LIST_PERSIST))
05620           {
05621             dirty++;
05622 #ifdef CONFIG_RSBAC_DEBUG
05623             if(rsbac_debug_lists)
05624               {
05625                 rsbac_printk(KERN_DEBUG
05626                        "rsbac_check_lists(): %s on %02u:%02u has %u items and %lu subitems (list is dirty)\n",
05627                        lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, subitem_count);
05628               }
05629 #endif
05630           }
05631 #ifdef CONFIG_RSBAC_DEBUG
05632         else
05633           {
05634             if(rsbac_debug_lists)
05635               {
05636                 rsbac_printk(KERN_DEBUG
05637                        "rsbac_check_lists(): %s on %02u:%02u has %u items and %lu subitems\n",
05638                        lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, subitem_count);
05639               }
05640           }
05641 #endif
05642         lol_list = lol_list->next;
05643       }
05644     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
05645     return 0;
05646   }
05647 
05648 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
05649 EXPORT_SYMBOL(rsbac_list_check);
05650 #endif
05651 int rsbac_list_check(
05652   rsbac_list_handle_t handle,
05653   int correct)
05654   {
05655     struct rsbac_list_reg_item_t * list;
05656     struct rsbac_list_item_t     * item_p;
05657     struct rsbac_list_item_t     * next_item_p;
05658     u_long lock_flags;
05659     u_long rlock_flags;
05660     u_long tmp_count;
05661 
05662     if(!handle)
05663       return -RSBAC_EINVALIDVALUE;
05664     if(!list_initialized)
05665       return -RSBAC_ENOTINITIALIZED;
05666 
05667     list = (struct rsbac_list_reg_item_t *) handle;
05668     if(!list || (list->self != list))
05669       return -RSBAC_EINVALIDVALUE;
05670 
05671     rsbac_read_lock(&reg_head.lock, &rlock_flags);
05672 #ifdef CONFIG_RSBAC_DEBUG
05673     if(rsbac_debug_lists)
05674       rsbac_printk(KERN_DEBUG "rsbac_list_check: checking list %s.\n",
05675              list->name);
05676 #endif
05677     rsbac_write_lock(&list->lock, &lock_flags);
05678     tmp_count = 0;
05679     item_p = list->head;
05680     while(item_p)
05681       {
05682         if(   (   item_p->max_age
05683                && (item_p->max_age <= RSBAC_CURRENT_TIME)
05684               )
05685            || (   list->def_data
05686                && !memcmp(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
05687                           list->def_data,
05688                           list->info.data_size)
05689               )
05690           )
05691           {
05692             next_item_p = item_p->next;
05693             do_remove_item(list, item_p);
05694             item_p = next_item_p;
05695             list->dirty = TRUE;
05696           }
05697         else
05698           {
05699             tmp_count++;
05700             item_p = item_p->next;
05701           }
05702       }
05703     if(tmp_count != list->count)
05704       {
05705         if(correct)
05706           {
05707             rsbac_printk(KERN_WARNING
05708                          "rsbac_list_check(): correcting count mismatch for list %s on device %02u:%02u - was %u, counted %lu!\n",
05709                          list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count);
05710             list->count = tmp_count;
05711             list->dirty = TRUE;
05712           }
05713         else
05714           {
05715             rsbac_printk(KERN_WARNING
05716                          "rsbac_list_check(): count mismatch for list %s on device %02u:%02u - is %u, counted %lu!\n",
05717                          list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count);
05718           }
05719       }
05720     rsbac_write_unlock(&list->lock, &lock_flags);
05721     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
05722     return 0;
05723   }
05724 
05725 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
05726 EXPORT_SYMBOL(rsbac_list_lol_check);
05727 #endif
05728 int rsbac_list_lol_check(
05729   rsbac_list_handle_t handle,
05730   int correct)
05731   {
05732     struct rsbac_list_lol_reg_item_t * lol_list;
05733     struct rsbac_list_lol_item_t     * lol_item_p;
05734     struct rsbac_list_lol_item_t     * next_lol_item_p;
05735     struct rsbac_list_item_t         * lol_subitem_p;
05736     struct rsbac_list_item_t         * next_lol_subitem_p;
05737     u_long lock_flags;
05738     u_long rlock_flags;
05739     u_long tmp_count;
05740     u_long tmp_subcount;
05741 
05742     if(!handle)
05743       return -RSBAC_EINVALIDVALUE;
05744     if(!list_initialized)
05745       return -RSBAC_ENOTINITIALIZED;
05746 
05747     lol_list = (struct rsbac_list_lol_reg_item_t *) handle;
05748     if(!lol_list || (lol_list->self != lol_list))
05749       return -RSBAC_EINVALIDVALUE;
05750 
05751     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
05752 #ifdef CONFIG_RSBAC_DEBUG
05753     if(rsbac_debug_lists)
05754       rsbac_printk(KERN_DEBUG "rsbac_list_lol_check: checking list %s.\n",
05755              lol_list->name);
05756 #endif
05757     rsbac_write_lock(&lol_list->lock, &lock_flags);
05758     tmp_count = 0;
05759     lol_item_p = lol_list->head;
05760     while(lol_item_p)
05761       {
05762         if(   (   lol_item_p->max_age
05763                && (lol_item_p->max_age <= RSBAC_CURRENT_TIME)
05764               )
05765            || (   lol_list->def_data
05766                && !lol_item_p->count
05767                && !memcmp(((char *) lol_item_p) + sizeof(*lol_item_p) + lol_list->info.desc_size,
05768                           lol_list->def_data,
05769                           lol_list->info.data_size)
05770               )
05771            || (   !lol_list->info.data_size
05772                && (lol_list->flags & RSBAC_LIST_DEF_DATA)
05773                && !lol_item_p->count
05774               )
05775           )
05776           {
05777             next_lol_item_p = lol_item_p->next;
05778             do_remove_lol_item(lol_list, lol_item_p);
05779             lol_item_p = next_lol_item_p;
05780           }
05781         else
05782           {
05783             tmp_count++;
05784             tmp_subcount = 0;
05785             lol_subitem_p = lol_item_p->head;
05786             while(lol_subitem_p)
05787               {
05788                 if(   (   lol_subitem_p->max_age
05789                        && (lol_subitem_p->max_age <= RSBAC_CURRENT_TIME)
05790                       )
05791                    || (   lol_list->def_subdata
05792                        && !memcmp(((char *) lol_subitem_p) + sizeof(*lol_subitem_p) + lol_list->info.subdesc_size,
05793                                   lol_list->def_subdata,
05794                                   lol_list->info.subdata_size)
05795                       )
05796                   )
05797                   {
05798                     next_lol_subitem_p = lol_subitem_p->next;
05799                     do_remove_lol_subitem(lol_item_p, lol_subitem_p);
05800                     lol_subitem_p = next_lol_subitem_p;
05801                   }
05802                 else
05803                   {
05804                     tmp_subcount++;
05805                     lol_subitem_p = lol_subitem_p->next;
05806                   }
05807               }
05808             if(tmp_subcount != lol_item_p->count)
05809               {
05810                 if(correct)
05811                   {
05812                      rsbac_printk(KERN_WARNING
05813                                   "rsbac_list_lol_check(): correcting count mismatch for list of lists %s sublist on %02u:%02u - was %lu, counted %lu!\n",
05814                                   lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount);
05815                     lol_item_p->count = tmp_subcount;
05816                   }
05817                 else
05818                   {
05819                     rsbac_printk(KERN_WARNING
05820                                  "rsbac_list_lol_check(): count mismatch for list of lists %s sublist on %02u:%02u - is %lu, counted %lu!\n",
05821                                  lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount);
05822                   }
05823               }
05824             lol_item_p = lol_item_p->next;
05825           }
05826       }
05827     if(tmp_count != lol_list->count)
05828       {
05829         if(correct)
05830           {
05831             rsbac_printk(KERN_WARNING
05832                          "rsbac_list_lol_check(): correcting count mismatch for list of lists %s on %02u:%02u - was %u, counted %lu!\n",
05833                          lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count);
05834             lol_list->count = tmp_count;
05835           }
05836         else
05837           {
05838             rsbac_printk(KERN_WARNING
05839                          "rsbac_list_lol_check(): count mismatch for list of lists %s on %02u:%02u - is %u, counted %lu!\n",
05840                          lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count);
05841           }
05842       }
05843     rsbac_write_unlock(&lol_list->lock, &lock_flags);
05844     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
05845     return 0;
05846   }
05847 
05848 
05849 /********************/
05850 /* Registration     */
05851 /********************/
05852 
05853 /* get generic list registration version */
05854 rsbac_version_t rsbac_list_version(void)
05855   {
05856     return RSBAC_LIST_VERSION;
05857   }
05858 
05859 /* register a new list */
05860 /*
05861  * If list with same name exists in memory, error -RSBAC_EEXISTS is returned.
05862  * If list with same name and key exists on device, it is restored depending on the flags.
05863  * If list with same name, but different key exists, access is denied (error -EPERM).
05864  *
05865  * ds_version: for binary modules, must be RSBAC_LIST_VERSION. If version differs, return error.
05866  * handle_p: for all list accesses, an opaque handle is put into *handle_p.
05867  * key: positive, secret __u32 key, which must be the same as in on-disk version, if persistent
05868  * list_version: positive __u32 version number for the list. If old on-disk version is
05869    different, upconversion is tried (depending on flags and get_conv function)
05870  * flags: see flag values
05871  * desc_size: size of the descriptor (error is returned, if value is 0 or list exists and value differs)
05872  * data_size: size of data (error is returned, if list exists and value differs). Can be 0 for sets.
05873  * compare: for lookup and list optimization, can be NULL, then
05874    memcmp(desc1, desc2, desc_size) is used
05875  * def_data: default data value for flag RSBAC_LIST_DEF_DATA
05876    (if NULL, flag is cleared)
05877  * name: the on-disk name, must be distinct and max. 7 or 8.2 chars
05878    (only used for statistics, if non-persistent)
05879  * device: the device to read list from or to save list to - use 0 for root dev
05880    (ignored, if non-persistent)
05881  */
05882 
05883 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
05884 EXPORT_SYMBOL(rsbac_list_register);
05885 #endif
05886 int rsbac_list_register(
05887   rsbac_version_t ds_version,
05888   rsbac_list_handle_t *handle_p,
05889   struct rsbac_list_info_t * info_p,
05890   u_int flags,
05891   rsbac_list_compare_function_t * compare,
05892   rsbac_list_get_conv_t * get_conv,
05893   void * def_data,
05894   char * name,
05895   kdev_t device)
05896   {
05897     struct rsbac_list_reg_item_t     * reg_item_p;
05898     struct rsbac_list_reg_item_t     * new_reg_item_p;
05899     u_long lock_flags;
05900     int    err = 0;
05901 
05902     if(ds_version != RSBAC_LIST_VERSION)
05903       {
05904         if(name)
05905           {
05906             rsbac_printk(KERN_WARNING
05907                    "rsbac_list_register: wrong ds_version %u for list %s, expected %u!\n",
05908                    ds_version,
05909                    name,
05910                    RSBAC_LIST_VERSION);
05911           }
05912         return -RSBAC_EINVALIDVERSION;
05913       }
05914     if(!handle_p || !info_p)
05915       return -RSBAC_EINVALIDPOINTER;
05916     *handle_p = NULL;
05917     if(!info_p->key || !info_p->version || !info_p->desc_size)
05918       return -RSBAC_EINVALIDVALUE;
05919     if(info_p->max_age > RSBAC_LIST_MAX_AGE_LIMIT)
05920       return -RSBAC_EINVALIDVALUE;
05921     if(info_p->desc_size + info_p->data_size > RSBAC_LIST_MAX_ITEM_SIZE)
05922       return -RSBAC_EINVALIDVALUE;
05923     if(!list_initialized)
05924       return -RSBAC_ENOTINITIALIZED;
05925     if(name)
05926       {
05927         struct rsbac_list_lol_reg_item_t * lol_reg_item_p;
05928 
05929         rsbac_read_lock(&reg_head.lock, &lock_flags);
05930         reg_item_p = lookup_reg_name(name, device);
05931         rsbac_read_unlock(&reg_head.lock, &lock_flags);
05932         if(reg_item_p)
05933           {
05934 #ifdef CONFIG_RSBAC_DEBUG
05935             if(rsbac_debug_lists)
05936               {
05937                 rsbac_printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n",
05938                        name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
05939               }
05940 #endif
05941             return -RSBAC_EEXISTS;
05942           }
05943         rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
05944         lol_reg_item_p = lookup_lol_reg_name(name, device);
05945         rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
05946         if(lol_reg_item_p)
05947           {
05948 #ifdef CONFIG_RSBAC_DEBUG
05949             if(rsbac_debug_lists)
05950               {
05951                 rsbac_printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n",
05952                        name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
05953               }
05954 #endif
05955             return -RSBAC_EEXISTS;
05956           }
05957       }
05958     else
05959       if(flags & RSBAC_LIST_PERSIST)
05960         {
05961           rsbac_printk(KERN_WARNING
05962                  "rsbac_list_register: trial to register persistent list without name.\n");
05963           return -RSBAC_EINVALIDVALUE;
05964         }
05965 
05966     if(flags & RSBAC_LIST_PERSIST)
05967       {
05968         if(RSBAC_IS_AUTO_DEV(device))
05969           device = rsbac_root_dev;
05970         if(!RSBAC_MAJOR(device))
05971           flags &= ~RSBAC_LIST_PERSIST;
05972       }
05973 
05974 #ifdef CONFIG_RSBAC_DEBUG
05975     if(rsbac_debug_lists)
05976       {
05977         rsbac_printk(KERN_DEBUG "rsbac_list_register: registering list %s for device %02u:%02u.\n",
05978                name, RSBAC_MAJOR(device),RSBAC_MINOR(device));
05979       }
05980 #endif
05981     new_reg_item_p = create_reg(info_p, flags, compare, get_conv, def_data, name, device);
05982     if(!new_reg_item_p)
05983       {
05984         return -RSBAC_ECOULDNOTADDITEM;
05985       }
05986     /* Restore from disk, but only for real device mounts */
05987     if(   (flags & RSBAC_LIST_PERSIST)
05988        && RSBAC_MAJOR(device)
05989       )
05990       {
05991 #ifdef CONFIG_RSBAC_DEBUG
05992         if(rsbac_debug_lists)
05993           {
05994             rsbac_printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u.\n",
05995                    name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
05996           }
05997 #endif
05998         err = read_list(new_reg_item_p);
05999         /* not found is no error */
06000         if(err == -RSBAC_ENOTFOUND)
06001           err = 0;
06002         else
06003         if(err)
06004           {
06005 #ifdef CONFIG_RSBAC_DEBUG
06006             if(rsbac_debug_lists)
06007               {
06008                 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
06009 
06010                 if(tmp)
06011                   {
06012                     get_error_name(tmp, err);
06013                     rsbac_printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u failed with error %s, unregistering list.\n",
06014                            name,
06015                            RSBAC_MAJOR(device),RSBAC_MINOR(device),
06016                            tmp);
06017                     rsbac_kfree(tmp);
06018                   }
06019               }
06020 #endif
06021             clear_reg(new_reg_item_p);
06022             return err;
06023           }
06024 #ifdef CONFIG_RSBAC_DEBUG
06025         else
06026           {
06027             if(rsbac_debug_lists)
06028               {
06029                 rsbac_printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u was successful.\n",
06030                        name,
06031                        RSBAC_MAJOR(device),RSBAC_MINOR(device));
06032               }
06033           }
06034 #endif
06035       }
06036 
06037     rsbac_write_lock(&reg_head.lock, &lock_flags);
06038     reg_item_p = add_reg(new_reg_item_p);
06039     rsbac_write_unlock(&reg_head.lock, &lock_flags);
06040     if(!reg_item_p)
06041       {
06042         rsbac_printk(KERN_WARNING
06043                "rsbac_list_register: inserting list %s failed!\n",
06044                name);
06045         /* cleanup */
06046         clear_reg(new_reg_item_p);
06047         return -RSBAC_ECOULDNOTADDITEM;
06048       }
06049 
06050     /* finish */
06051 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06052     /* create proc entry, if requested */
06053     if(flags & RSBAC_LIST_BACKUP)
06054       {
06055         reg_item_p->proc_entry_p = create_proc_entry(reg_item_p->name,
06056                                                      S_IFREG | S_IRUGO,
06057                                                      proc_rsbac_backup_p);
06058         if(reg_item_p->proc_entry_p)
06059           {
06060             reg_item_p->proc_entry_p->read_proc = backup_proc_read;
06061             reg_item_p->proc_entry_p->data = reg_item_p;
06062           }
06063       }
06064     else
06065       {
06066         reg_item_p->proc_entry_p = NULL;
06067       }
06068 #endif
06069     *handle_p = reg_item_p;
06070     return err;
06071   }
06072 
06073 /* register a new list of lists */
06074 /*
06075  * If list with same name exists in memory, error -RSBAC_EEXISTS is returned.
06076  * If list with same name and key exists on device, it is restored depending on the flags.
06077  * If list with same name, but different key exists, access is denied (error -EPERM).
06078  *
06079  * ds_version: for binary modules, must be RSBAC_LIST_VERSION. If version differs, return error.
06080  * handle_p: for all list accesses, an opaque handle is put into *handle_p.
06081  * key: positive, secret __u32 key, which must be the same as in on-disk version, if persistent
06082  * list_version: positive __u32 version number for the list. If old on-disk version is
06083    different, upconversion is tried (depending on flags and get_conv function)
06084  * flags: see flag values
06085  * desc_size: size of the descriptor (error is returned, if value is 0 or list exists and value differs)
06086  * subdesc_size: size of the sublist descriptor (error is returned, if value is 0 or list exists
06087    and value differs)
06088  * data_size: size of data (error is returned, if list exists and value differs). Can be 0 for sets.
06089  * subdata_size: size of sublist data (error is returned, if list exists and value differs).
06090    Can be 0 for sets.
06091  * compare: for lookup and list optimization, can be NULL, then
06092    memcmp(desc1, desc2, desc_size) is used
06093  * subcompare: for item lookup and optimization of sublist, can be NULL, then
06094    memcmp(desc1, desc2, desc_size) is used
06095  * def_data: default data value for flag RSBAC_LIST_DEF_DATA
06096    (if NULL, flag is cleared)
06097  * def_subdata: default subdata value for flag RSBAC_LIST_DEF_SUBDATA
06098    (if NULL, flag is cleared)
06099  * name: the on-disk name, must be distinct and max. 7 or 8.2 chars
06100    (only used for info, if non-persistent)
06101  * device: the device to read list from or to save list to - use 0 for root dev
06102    (ignored, if non-persistent)
06103  */
06104 
06105 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06106 EXPORT_SYMBOL(rsbac_list_lol_register);
06107 #endif
06108 int rsbac_list_lol_register(
06109   rsbac_version_t ds_version,
06110   rsbac_list_handle_t *handle_p,
06111   struct rsbac_list_lol_info_t * info_p,
06112   u_int flags,
06113   rsbac_list_compare_function_t * compare,
06114   rsbac_list_compare_function_t * subcompare,
06115   rsbac_list_get_conv_t * get_conv,
06116   rsbac_list_get_conv_t * get_subconv,
06117   void * def_data,
06118   void * def_subdata,
06119   char * name,
06120   kdev_t device)
06121   {
06122     struct rsbac_list_lol_reg_item_t * reg_item_p;
06123     struct rsbac_list_lol_reg_item_t * new_reg_item_p;
06124     u_long lock_flags;
06125     int    err = 0;
06126 
06127     if(ds_version != RSBAC_LIST_VERSION)
06128       return -RSBAC_EINVALIDVERSION;
06129     if(!handle_p)
06130       return -RSBAC_EINVALIDPOINTER;
06131     *handle_p = NULL;
06132     if(!info_p->key || !info_p->version || !info_p->desc_size)
06133       return -RSBAC_EINVALIDVALUE;
06134     if(info_p->max_age > RSBAC_LIST_MAX_AGE_LIMIT)
06135       return -RSBAC_EINVALIDVALUE;
06136     if(info_p->desc_size + info_p->data_size > RSBAC_LIST_MAX_ITEM_SIZE)
06137       return -RSBAC_EINVALIDVALUE;
06138     if(info_p->subdesc_size + info_p->subdata_size > RSBAC_LIST_MAX_ITEM_SIZE)
06139       return -RSBAC_EINVALIDVALUE;
06140     if(!list_initialized)
06141       return -RSBAC_ENOTINITIALIZED;
06142     if(name)
06143       {
06144         struct rsbac_list_reg_item_t     * std_reg_item_p;
06145 
06146         rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
06147         reg_item_p = lookup_lol_reg_name(name, device);
06148         rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06149         if(reg_item_p)
06150           {
06151 #ifdef CONFIG_RSBAC_DEBUG
06152             if(rsbac_debug_lists)
06153               {
06154                 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: list name %s already exists on device %02u:%02u!\n",
06155                        name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
06156               }
06157 #endif
06158             return -RSBAC_EEXISTS;
06159           }
06160         rsbac_read_lock(&reg_head.lock, &lock_flags);
06161         std_reg_item_p = lookup_reg_name(name, device);
06162         rsbac_read_unlock(&reg_head.lock, &lock_flags);
06163         if(std_reg_item_p)
06164           {
06165 #ifdef CONFIG_RSBAC_DEBUG
06166             if(rsbac_debug_lists)
06167               {
06168                 rsbac_printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n",
06169                        name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
06170               }
06171 #endif
06172             return -RSBAC_EEXISTS;
06173           }
06174       }
06175     else
06176       if(flags & RSBAC_LIST_PERSIST)
06177         {
06178           rsbac_printk(KERN_WARNING
06179                  "rsbac_list_lol_register: trial to register persistent list of lists without name.\n");
06180           return -RSBAC_EINVALIDVALUE;
06181         }
06182 
06183     if(flags & RSBAC_LIST_PERSIST)
06184       {
06185         if(RSBAC_IS_AUTO_DEV(device))
06186           device = rsbac_root_dev;
06187         if(!RSBAC_MAJOR(device))
06188           flags &= ~RSBAC_LIST_PERSIST;
06189       }
06190 
06191 #ifdef CONFIG_RSBAC_DEBUG
06192     if(rsbac_debug_lists)
06193       {
06194         rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: registering list of lists %s.\n",
06195                name);
06196       }
06197 #endif
06198     new_reg_item_p = create_lol_reg(info_p, flags, compare, subcompare,
06199                                     get_conv, get_subconv,
06200                                     def_data, def_subdata,
06201                                     name, device);
06202     if(!new_reg_item_p)
06203       {
06204         return -RSBAC_ECOULDNOTADDITEM;
06205       }
06206     /* Restore from disk */
06207     if(flags & RSBAC_LIST_PERSIST)
06208       {
06209 #ifdef CONFIG_RSBAC_DEBUG
06210         if(rsbac_debug_lists)
06211           {
06212             rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u.\n",
06213                    name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
06214           }
06215 #endif
06216         err = read_lol_list(new_reg_item_p);
06217         /* not found is no error */
06218         if(err == -RSBAC_ENOTFOUND)
06219           err = 0;
06220         else
06221         if(err)
06222           {
06223 #ifdef CONFIG_RSBAC_DEBUG
06224             if(rsbac_debug_lists)
06225               {
06226                 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
06227 
06228                 if(tmp)
06229                   {
06230                     get_error_name(tmp, err);
06231                     rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u failed with error %s, unregistering list.\n",
06232                            name,
06233                            RSBAC_MAJOR(device),RSBAC_MINOR(device),
06234                            tmp);
06235                     rsbac_kfree(tmp);
06236                   }
06237               }
06238 #endif
06239             clear_lol_reg(new_reg_item_p);
06240             return err;
06241           }
06242 #ifdef CONFIG_RSBAC_DEBUG
06243         else
06244           {
06245             if(rsbac_debug_lists)
06246               {
06247                 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u was successful.\n",
06248                        name,
06249                        RSBAC_MAJOR(device),RSBAC_MINOR(device));
06250               }
06251           }
06252 #endif
06253       }
06254 
06255     rsbac_write_lock(&lol_reg_head.lock, &lock_flags);
06256     reg_item_p = add_lol_reg(new_reg_item_p);
06257     rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06258     if(!reg_item_p)
06259       {
06260         rsbac_printk(KERN_WARNING
06261                "rsbac_list_lol_register: inserting list %s failed!\n",
06262                name);
06263         /* cleanup */
06264         clear_lol_reg(new_reg_item_p);
06265         return -RSBAC_ECOULDNOTADDITEM;
06266       }
06267 
06268     /* finish */
06269 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06270     /* create proc entry, if requested */
06271     if(flags & RSBAC_LIST_BACKUP)
06272       {
06273         reg_item_p->proc_entry_p = create_proc_entry(reg_item_p->name,
06274                                                      S_IFREG | S_IRUGO,
06275                                                      proc_rsbac_backup_p);
06276         if(reg_item_p->proc_entry_p)
06277           {
06278             reg_item_p->proc_entry_p->read_proc = lol_backup_proc_read;
06279             reg_item_p->proc_entry_p->data = reg_item_p;
06280           }
06281       }
06282     else
06283       {
06284         reg_item_p->proc_entry_p = NULL;
06285       }
06286 #endif
06287     *handle_p = reg_item_p;
06288     return err;
06289   }
06290 
06291 /* destroy list */
06292 /* list is destroyed, disk file is deleted */
06293 /* list must have been opened with register */
06294 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06295 EXPORT_SYMBOL(rsbac_list_destroy);
06296 #endif
06297 int rsbac_list_destroy(rsbac_list_handle_t * handle_p, rsbac_list_key_t key)
06298   {
06299     struct rsbac_list_reg_item_t * reg_item_p;
06300     u_long lock_flags;
06301     int err = 0;
06302 
06303     if(!handle_p)
06304       return -RSBAC_EINVALIDPOINTER;
06305     if(!*handle_p)
06306       return -RSBAC_EINVALIDVALUE;
06307     if(!list_initialized)
06308       return -RSBAC_ENOTINITIALIZED;
06309 
06310     rsbac_write_lock(&reg_head.lock, &lock_flags);
06311     reg_item_p = lookup_reg((struct rsbac_list_reg_item_t *) *handle_p);
06312     if(!reg_item_p)
06313       {
06314         rsbac_write_unlock(&reg_head.lock, &lock_flags);
06315         rsbac_printk(KERN_WARNING "rsbac_list_destroy: destroying list failed due to invalid handle!\n");
06316         return -RSBAC_EINVALIDVALUE;
06317       }
06318     if(reg_item_p->info.key != key)
06319       {
06320         rsbac_write_unlock(&reg_head.lock, &lock_flags);
06321         rsbac_printk(KERN_WARNING "rsbac_list_destroy: destroying list %s denied due to invalid key!\n",
06322                reg_item_p->name);
06323         return -EPERM;
06324       }
06325 #ifdef CONFIG_RSBAC_DEBUG
06326     if(rsbac_debug_lists)
06327       {
06328         rsbac_printk(KERN_DEBUG "rsbac_list_destroy: destroying list %s.\n",
06329                reg_item_p->name);
06330       }
06331 #endif
06332 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06333     /* delete proc entry, if it exists */
06334     if(   (reg_item_p->flags & RSBAC_LIST_BACKUP)
06335        && reg_item_p->proc_entry_p
06336       )
06337       {
06338         remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p);
06339         reg_item_p->proc_entry_p = NULL;
06340       }
06341 #endif
06342 
06343 #if 0
06344     if(reg_item_p->flags & RSBAC_LIST_PERSIST)
06345       err = unlink_list(reg_item_p);
06346 #endif
06347 
06348     remove_reg(reg_item_p);
06349     *handle_p = NULL; 
06350     rsbac_write_unlock(&reg_head.lock, &lock_flags);
06351     return err;
06352   }
06353 
06354 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06355 EXPORT_SYMBOL(rsbac_list_lol_destroy);
06356 #endif
06357 int rsbac_list_lol_destroy(rsbac_list_handle_t * handle_p, rsbac_list_key_t key)
06358   {
06359     struct rsbac_list_lol_reg_item_t * reg_item_p;
06360     u_long lock_flags;
06361     int err = 0;
06362 
06363     if(!handle_p)
06364       return -RSBAC_EINVALIDPOINTER;
06365     if(!*handle_p)
06366       return -RSBAC_EINVALIDVALUE;
06367     if(!list_initialized)
06368       return -RSBAC_ENOTINITIALIZED;
06369 
06370     rsbac_write_lock(&lol_reg_head.lock, &lock_flags);
06371     reg_item_p = lookup_lol_reg((struct rsbac_list_lol_reg_item_t *) *handle_p);
06372     if(!reg_item_p)
06373       {
06374         rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06375         rsbac_printk(KERN_WARNING "rsbac_list_lol_destroy: destroying list failed due to invalid handle!\n");
06376         return -RSBAC_EINVALIDVALUE;
06377       }
06378     if(reg_item_p->info.key != key)
06379       {
06380         rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06381         rsbac_printk(KERN_WARNING "rsbac_list_lol_destroy: destroying list %s denied due to invalid key %u!\n",
06382                reg_item_p->name,
06383                key);
06384         return -EPERM;
06385       }
06386 #ifdef CONFIG_RSBAC_DEBUG
06387     if(rsbac_debug_lists)
06388       {
06389         rsbac_printk(KERN_DEBUG "rsbac_list_lol_destroy: destroying list %s.\n",
06390                reg_item_p->name);
06391       }
06392 #endif
06393 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06394     /* delete proc entry, if it exists */
06395     if(   (reg_item_p->flags & RSBAC_LIST_BACKUP)
06396        && reg_item_p->proc_entry_p
06397       )
06398       {
06399         remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p);
06400         reg_item_p->proc_entry_p = NULL;
06401       }
06402 #endif
06403 #if 0
06404     if(reg_item_p->flags & RSBAC_LIST_PERSIST)
06405       err = unlink_lol_list(reg_item_p);
06406 #endif
06407 
06408     remove_lol_reg(reg_item_p);
06409     *handle_p = NULL; 
06410     rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06411     return err;
06412   }
06413 
06414 /* detach from list */
06415 /* list is saved and removed from memory. Call register for new access. */
06416 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06417 EXPORT_SYMBOL(rsbac_list_detach);
06418 #endif
06419 int rsbac_list_detach(rsbac_list_handle_t * handle_p, rsbac_list_key_t key)
06420   {
06421     struct rsbac_list_reg_item_t * reg_item_p;
06422     u_long lock_flags;
06423     int err = 0;
06424 
06425     if(!handle_p)
06426       return -RSBAC_EINVALIDPOINTER;
06427     if(!*handle_p)
06428       return -RSBAC_EINVALIDVALUE;
06429     if(!list_initialized)
06430       return -RSBAC_ENOTINITIALIZED;
06431 
06432     rsbac_read_lock(&reg_head.lock, &lock_flags);
06433     reg_item_p = lookup_reg((struct rsbac_list_reg_item_t *) *handle_p);
06434     if(!reg_item_p)
06435       {
06436         rsbac_read_unlock(&reg_head.lock, &lock_flags);
06437         rsbac_printk(KERN_WARNING "rsbac_list_detach: detaching list failed due to invalid handle!\n");
06438         return -RSBAC_EINVALIDVALUE;
06439       }
06440     if(reg_item_p->info.key != key)
06441       {
06442         rsbac_read_unlock(&reg_head.lock, &lock_flags);
06443         rsbac_printk(KERN_WARNING "rsbac_list_detach: detaching list %s denied due to invalid key %u!\n",
06444                reg_item_p->name,
06445                key);
06446         return -EPERM;
06447       }
06448 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06449     /* delete proc entry, if it exists */
06450     if(   (reg_item_p->flags & RSBAC_LIST_BACKUP)
06451        && reg_item_p->proc_entry_p
06452       )
06453       {
06454         remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p);
06455         reg_item_p->proc_entry_p = NULL;
06456       }
06457 #endif
06458 #ifndef CONFIG_RSBAC_NO_WRITE
06459     /* final write, if dirty etc. */
06460     if(   (reg_item_p->flags & RSBAC_LIST_PERSIST)
06461        && reg_item_p->dirty
06462        && !reg_item_p->no_write
06463       )
06464       {
06465         struct rsbac_list_write_head_t       write_head;
06466         struct rsbac_list_write_item_t     * write_item_p;
06467 
06468         reg_item_p->dirty = FALSE;
06469         err = fill_buffer(reg_item_p, &write_item_p);
06470         if(!err)
06471           {
06472             write_head.head = write_item_p;
06473             write_head.tail = write_item_p;
06474             write_head.total = write_item_p->buflen;
06475             write_head.count = 1;
06476             rsbac_read_unlock(&reg_head.lock, &lock_flags);
06477             rsbac_list_write_buffers(write_head, TRUE);
06478           }
06479         else
06480           {
06481             rsbac_read_unlock(&reg_head.lock, &lock_flags);
06482             if(err != -RSBAC_ENOTWRITABLE)
06483               {
06484                 rsbac_printk(KERN_WARNING
06485                        "rsbac_list_detach(): fill_buffer() for list %s returned error %i\n",
06486                        reg_item_p->name, err);
06487               }
06488           }
06489       }
06490     else
06491       rsbac_read_unlock(&reg_head.lock, &lock_flags);
06492 #else
06493     rsbac_read_unlock(&reg_head.lock, &lock_flags);
06494 #endif
06495     /* disable handle */
06496     *handle_p = NULL; 
06497     /* too bad that the list might have been changed again - we do not care anymore */
06498     rsbac_write_lock(&reg_head.lock, &lock_flags);
06499     remove_reg(reg_item_p);
06500     rsbac_write_unlock(&reg_head.lock, &lock_flags);
06501     return err;
06502   }
06503 
06504 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06505 EXPORT_SYMBOL(rsbac_list_lol_detach);
06506 #endif
06507 int rsbac_list_lol_detach(rsbac_list_handle_t * handle_p, rsbac_list_key_t key)
06508   {
06509     struct rsbac_list_lol_reg_item_t * reg_item_p;
06510     u_long lock_flags;
06511     int err = 0;
06512 
06513     if(!handle_p)
06514       return -RSBAC_EINVALIDPOINTER;
06515     if(!*handle_p)
06516       return -RSBAC_EINVALIDVALUE;
06517     if(!list_initialized)
06518       return -RSBAC_ENOTINITIALIZED;
06519 
06520     rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
06521     reg_item_p = lookup_lol_reg((struct rsbac_list_lol_reg_item_t *) *handle_p);
06522     if(!reg_item_p)
06523       {
06524         rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06525         rsbac_printk(KERN_WARNING "rsbac_list_lol_detach: detaching list failed due to invalid handle!\n");
06526         return -RSBAC_EINVALIDVALUE;
06527       }
06528     if(reg_item_p->info.key != key)
06529       {
06530         rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06531         rsbac_printk(KERN_WARNING "rsbac_list_lol_detach: detaching list %s denied due to invalid key %u!\n",
06532                reg_item_p->name,
06533                key);
06534         return -EPERM;
06535       }
06536 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06537     /* delete proc entry, if it exists */
06538     if(   (reg_item_p->flags & RSBAC_LIST_BACKUP)
06539        && reg_item_p->proc_entry_p
06540       )
06541       {
06542         remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p);
06543         reg_item_p->proc_entry_p = NULL;
06544       }
06545 #endif
06546 #ifndef CONFIG_RSBAC_NO_WRITE
06547     /* final write, if dirty etc. */
06548     if(   (reg_item_p->flags & RSBAC_LIST_PERSIST)
06549        && reg_item_p->dirty
06550        && !reg_item_p->no_write
06551       )
06552       {
06553         struct rsbac_list_lol_write_head_t       write_head;
06554         struct rsbac_list_lol_write_item_t     * write_item_p;
06555 
06556         reg_item_p->dirty = FALSE;
06557         err = fill_lol_buffer(reg_item_p, &write_item_p);
06558         if(!err)
06559           {
06560             write_head.head = write_item_p;
06561             write_head.tail = write_item_p;
06562             write_head.total = write_item_p->buflen;
06563             write_head.count = 1;
06564             rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06565             rsbac_list_write_lol_buffers(write_head, TRUE);
06566           }
06567         else
06568           {
06569             rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06570             if(err != -RSBAC_ENOTWRITABLE)
06571               {
06572                 rsbac_printk(KERN_WARNING
06573                        "rsbac_list_lol_detach(): fill_buffer() for list %s returned error %i\n",
06574                        reg_item_p->name, err);
06575               }
06576           }
06577       }
06578     else
06579       rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06580 #else
06581     rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06582 #endif
06583     /* disable handle */
06584     *handle_p = NULL; 
06585     /* too bad that the list might have been changed again - we do not care anymore */
06586     rsbac_write_lock(&lol_reg_head.lock, &lock_flags);
06587     remove_lol_reg(reg_item_p);
06588     rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06589     return err;
06590   }
06591 
06592 /* set list's no_write flag */
06593 /* TRUE: do not write to disk, FALSE: writing allowed */
06594 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06595 EXPORT_SYMBOL(rsbac_list_no_write);
06596 #endif
06597 int rsbac_list_no_write(rsbac_list_handle_t handle, rsbac_list_key_t key, rsbac_boolean_t no_write)
06598   {
06599     struct rsbac_list_reg_item_t * reg_item_p;
06600     u_long lock_flags;
06601 
06602     if(   !handle
06603        || (   (no_write != FALSE )
06604            && (no_write != TRUE )
06605           )
06606       )
06607       return -RSBAC_EINVALIDVALUE;
06608     if(!list_initialized)
06609       return -RSBAC_ENOTINITIALIZED;
06610 
06611     rsbac_read_lock(&reg_head.lock, &lock_flags);
06612     reg_item_p = lookup_reg((struct rsbac_list_reg_item_t *) handle);
06613     if(!reg_item_p)
06614       {
06615         rsbac_read_unlock(&reg_head.lock, &lock_flags);
06616         rsbac_printk(KERN_WARNING "rsbac_list_no_write: setting no_write for list denied due to invalid handle!\n");
06617         return -RSBAC_EINVALIDVALUE;
06618       }
06619     if(reg_item_p->info.key != key)
06620       {
06621         rsbac_read_unlock(&reg_head.lock, &lock_flags);
06622         rsbac_printk(KERN_WARNING "rsbac_list_no_write: setting no_write for list %s denied due to invalid key %u!\n",
06623                reg_item_p->name,
06624                key);
06625         return -EPERM;
06626       }
06627     reg_item_p->no_write = no_write;
06628     rsbac_read_unlock(&reg_head.lock, &lock_flags);
06629     return 0;
06630   }
06631 
06632 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06633 EXPORT_SYMBOL(rsbac_list_lol_no_write);
06634 #endif
06635 int rsbac_list_lol_no_write(rsbac_list_handle_t handle, rsbac_list_key_t key, rsbac_boolean_t no_write)
06636   {
06637     struct rsbac_list_lol_reg_item_t * reg_item_p;
06638     u_long lock_flags;
06639 
06640     if(   !handle
06641        || (   (no_write != FALSE )
06642            && (no_write != TRUE )
06643           )
06644       )
06645       return -RSBAC_EINVALIDVALUE;
06646     if(!list_initialized)
06647       return -RSBAC_ENOTINITIALIZED;
06648 
06649     rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
06650     reg_item_p = lookup_lol_reg((struct rsbac_list_lol_reg_item_t *) handle);
06651     if(!reg_item_p)
06652       {
06653         rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06654         rsbac_printk(KERN_WARNING "rsbac_list_lol_no_write: setting no_write for list denied due to invalid handle!\n");
06655         return -RSBAC_EINVALIDVALUE;
06656       }
06657     if(reg_item_p->info.key != key)
06658       {
06659         rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06660         rsbac_printk(KERN_WARNING "rsbac_list_lol_no_write: setting no_write for list %s denied due to invalid key %u!\n",
06661                reg_item_p->name,
06662                key);
06663         return -EPERM;
06664       }
06665     reg_item_p->no_write = no_write;
06666     rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06667     return 0;
06668   }
06669 
06670 
06671 /********************/
06672 /* Transactions     */
06673 /********************/
06674 
06675 #ifdef CONFIG_RSBAC_LIST_TRANS
06676 static int do_commit(rsbac_list_ta_number_t ta_number)
06677   {
06678     /* Get both big list and lol_list locks,
06679      * for all lists and lol_lists
06680      *   if ta_copied
06681      *     free all items
06682      *     move ta_head to head, ta_tail to tail, ta_curr to curr
06683      *     reset ta_copied
06684      *     set dirty
06685      *   endif
06686      * release both big locks
06687      */
06688     struct rsbac_list_reg_item_t     * list;
06689     struct rsbac_list_lol_reg_item_t * lol_list;
06690     u_long lock_flags;
06691     u_long lol_lock_flags;
06692 
06693     rsbac_write_lock(&reg_head.lock, &lock_flags);
06694     rsbac_write_lock(&lol_reg_head.lock, &lol_lock_flags);
06695     list = reg_head.head;
06696     while(list)
06697       {
06698         if(list->ta_copied == ta_number)
06699           {
06700             remove_all_items(list);
06701             list->head = list->ta_head;
06702             list->tail = list->ta_tail;
06703             list->curr = list->ta_curr;
06704             list->count = list->ta_count;
06705             list->ta_head = NULL;
06706             list->ta_tail = NULL;
06707             list->ta_curr = NULL;
06708             list->ta_count = 0;
06709             list->ta_copied = 0;
06710             list->dirty = TRUE;
06711           }
06712         list = list->next;
06713       }
06714     lol_list = lol_reg_head.head;
06715     while(lol_list)
06716       {
06717         if(lol_list->ta_copied == ta_number)
06718           {
06719             remove_all_lol_items(lol_list);
06720             lol_list->head = lol_list->ta_head;
06721             lol_list->tail = lol_list->ta_tail;
06722             lol_list->curr = lol_list->ta_curr;
06723             lol_list->count = lol_list->ta_count;
06724             lol_list->ta_head = NULL;
06725             lol_list->ta_tail = NULL;
06726             lol_list->ta_curr = NULL;
06727             lol_list->ta_count = 0;
06728             lol_list->ta_copied = 0;
06729             lol_list->dirty = TRUE;
06730           }
06731         lol_list = lol_list->next;
06732       }
06733     rsbac_write_unlock(&lol_reg_head.lock, &lol_lock_flags);
06734     rsbac_write_unlock(&reg_head.lock, &lock_flags);
06735 
06736     return 0;
06737   }
06738 
06739 int rsbac_list_ta_commit(rsbac_list_ta_number_t ta_number,
06740                          char * password)
06741   {
06742     int err;
06743     struct rsbac_list_ta_data_t ta_data;
06744 
06745     err = rsbac_list_get_data(ta_handle, &ta_number, &ta_data);
06746     if(err)
06747       return err;
06748     if(   (ta_data.commit_uid != RSBAC_ALL_USERS)
06749        && (ta_data.commit_uid != current->uid)
06750       )
06751       return -EPERM;
06752 
06753     if(ta_data.password[0])
06754       {
06755         if(!password)
06756           return -EPERM;
06757         if(strncmp(ta_data.password, password, RSBAC_LIST_TA_MAX_PASSLEN))
06758           return -EPERM;
06759       }
06760     spin_lock(&ta_lock);
06761     if(ta_committing || ta_forgetting)
06762       {
06763         spin_unlock(&ta_lock);
06764         return -RSBAC_EBUSY;
06765       }
06766     ta_committing = TRUE;
06767     spin_unlock(&ta_lock);
06768 
06769     rsbac_printk(KERN_INFO "rsbac_list_ta_commit(): committing transaction %u\n",
06770                  ta_number);
06771 
06772     err = do_commit(ta_number);
06773     if(!err)
06774       rsbac_list_remove(ta_handle, &ta_number);
06775     ta_committing = FALSE;
06776     return err;
06777   }
06778 
06779 static int do_forget(rsbac_list_ta_number_t ta_number)
06780   {
06781     struct rsbac_list_reg_item_t     * list;
06782     struct rsbac_list_lol_reg_item_t * lol_list;
06783     u_long lock_flags;
06784     u_long lol_lock_flags;
06785 
06786     spin_lock(&ta_lock);
06787     if(ta_committing || ta_forgetting)
06788       {
06789         spin_unlock(&ta_lock);
06790         return -RSBAC_EBUSY;
06791       }
06792     ta_forgetting = TRUE;
06793     spin_unlock(&ta_lock);
06794 
06795     rsbac_printk(KERN_INFO "rsbac_list_ta_forget(): removing transaction %u\n",
06796                  ta_number);
06797 
06798     /* Get both big list and lol_list locks,
06799      * for all lists and lol_lists
06800      *   if ta_copied
06801      *     free all ta_items
06802      *     reset ta_copied
06803      *   endif
06804      * release both big locks
06805      */
06806     rsbac_write_lock(&reg_head.lock, &lock_flags);
06807     rsbac_write_lock(&lol_reg_head.lock, &lol_lock_flags);
06808     list = reg_head.head;
06809     while(list)
06810       {
06811         if(list->ta_copied == ta_number)
06812           {
06813             ta_remove_all_items(list);
06814             list->ta_copied = 0;
06815           }
06816         list = list->next;
06817       }
06818     lol_list = lol_reg_head.head;
06819     while(lol_list)
06820       {
06821         if(lol_list->ta_copied == ta_number)
06822           {
06823             ta_remove_all_lol_items(lol_list);
06824             lol_list->ta_copied = 0;
06825           }
06826         lol_list = lol_list->next;
06827       }
06828     rsbac_write_unlock(&lol_reg_head.lock, &lol_lock_flags);
06829     rsbac_write_unlock(&reg_head.lock, &lock_flags);
06830 
06831     rsbac_list_remove(ta_handle, &ta_number);
06832     ta_forgetting = FALSE;
06833 
06834     return 0;
06835   }
06836 
06837 int rsbac_list_ta_forget(rsbac_list_ta_number_t ta_number,
06838                          char * password)
06839   {
06840     int err;
06841     struct rsbac_list_ta_data_t ta_data;
06842 
06843     err = rsbac_list_get_data(ta_handle, &ta_number, &ta_data);
06844     if(err)
06845       return err;
06846     if(   (ta_data.commit_uid != RSBAC_ALL_USERS)
06847        && (ta_data.commit_uid != current->uid)
06848       )
06849       return -EPERM;
06850     if(ta_data.password[0])
06851       {
06852         if(!password)
06853           return -EPERM;
06854         if(strncmp(ta_data.password, password, RSBAC_LIST_TA_MAX_PASSLEN))
06855           return -EPERM;
06856       }
06857     return do_forget(ta_number);
06858   }
06859 
06860 int rsbac_list_ta_begin(
06861   rsbac_time_t ttl,
06862   rsbac_list_ta_number_t * ta_number_p,
06863   rsbac_uid_t commit_uid,
06864   char * password)
06865   {
06866     int err;
06867     rsbac_list_ta_number_t ta;
06868     struct rsbac_list_ta_data_t ta_data;
06869 
06870 #ifdef CONFIG_RSBAC_LIST_TRANS_RANDOM_TA
06871     get_random_bytes(&ta, sizeof(ta));
06872 #else
06873     ta = ta_next++;
06874 #endif
06875     while(rsbac_list_exist(ta_handle, &ta))
06876       {
06877 #ifdef CONFIG_RSBAC_LIST_TRANS_RANDOM_TA
06878         get_random_bytes(&ta, sizeof(ta));
06879 #else
06880         ta = ta_next++;
06881 #endif
06882       }
06883     if(!ttl || (ttl > CONFIG_RSBAC_LIST_TRANS_MAX_TTL))
06884       ttl = CONFIG_RSBAC_LIST_TRANS_MAX_TTL;
06885 
06886     rsbac_printk(KERN_INFO "rsbac_list_ta_begin(): starting transaction %u with ttl of %us\n",
06887                  ta, ttl);
06888 
06889     ta_data.start = RSBAC_CURRENT_TIME;
06890     ta_data.timeout = ta_data.start + ttl;
06891     ta_data.commit_uid = commit_uid;
06892     if(password)
06893       {
06894         strncpy(ta_data.password, password, RSBAC_LIST_TA_MAX_PASSLEN - 1);
06895         ta_data.password[RSBAC_LIST_TA_MAX_PASSLEN - 1] = 0;
06896       }
06897     else
06898       ta_data.password[0] = 0;
06899     err = rsbac_list_add(ta_handle, &ta, &ta_data);
06900     if(!err)
06901       *ta_number_p = ta;
06902     return err;
06903   }
06904 
06905 int rsbac_list_ta_refresh(
06906   rsbac_time_t ttl,
06907   rsbac_list_ta_number_t ta_number,
06908   char * password)
06909   {
06910     struct rsbac_list_ta_data_t ta_data;
06911     int err;
06912 
06913     if(!rsbac_list_exist(ta_handle, &ta_number))
06914       {
06915         return -RSBAC_ENOTFOUND;
06916       }
06917     if(!ttl || (ttl > CONFIG_RSBAC_LIST_TRANS_MAX_TTL))
06918       ttl = CONFIG_RSBAC_LIST_TRANS_MAX_TTL;
06919 
06920     rsbac_printk(KERN_INFO "rsbac_list_ta_refresh(): refreshing transaction %u for %us\n",
06921                  ta_number, ttl);
06922 
06923     err = rsbac_list_get_data(ta_handle, &ta_number, &ta_data);
06924     if(err)
06925       return err;
06926     if(   (ta_data.commit_uid != RSBAC_ALL_USERS)
06927        && (ta_data.commit_uid != current->uid)
06928       )
06929       return -EPERM;
06930     if(ta_data.password[0])
06931       {
06932         if(!password)
06933           return -EPERM;
06934         if(strncmp(ta_data.password, password, RSBAC_LIST_TA_MAX_PASSLEN))
06935           return -EPERM;
06936       }
06937     ta_data.timeout = RSBAC_CURRENT_TIME + ttl;
06938     return rsbac_list_add(ta_handle, &ta_number, &ta_data);
06939   }
06940 #endif
06941 
06942 
06943 /********************/
06944 /* List Access      */
06945 /********************/
06946 
06947 /* add item */
06948 /* if item for desc exists, the data is updated */
06949 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06950 EXPORT_SYMBOL(rsbac_ta_list_add_ttl);
06951 #endif
06952 int rsbac_ta_list_add_ttl(
06953   rsbac_list_ta_number_t ta_number,
06954   rsbac_list_handle_t handle,
06955   rsbac_time_t ttl,
06956   void * desc,
06957   void * data)
06958   {
06959     struct rsbac_list_reg_item_t * list;
06960     struct rsbac_list_item_t     * item_p;
06961     u_long lock_flags, rlock_flags;
06962 
06963     if(!handle || !desc)
06964       return -RSBAC_EINVALIDVALUE;
06965     if(!list_initialized)
06966       return -RSBAC_ENOTINITIALIZED;
06967 
06968     list = (struct rsbac_list_reg_item_t *) handle;
06969     if(!list || (list->self != list))
06970       return -RSBAC_EINVALIDVALUE;
06971 
06972 #ifdef CONFIG_RSBAC_LIST_TRANS
06973     if(ta_number && !rsbac_ta_list_exist(0, ta_handle, &ta_number))
06974       return -RSBAC_EINVALIDTRANSACTION;
06975 #endif
06976 
06977     rsbac_read_lock(&reg_head.lock, &rlock_flags);
06978     if(list->info.data_size && !data)
06979       {
06980         rsbac_read_unlock(&reg_head.lock, &rlock_flags);
06981         return -RSBAC_EINVALIDVALUE;
06982       }
06983 
06984 /*
06985 #ifdef CONFIG_RSBAC_DEBUG
06986     if(rsbac_debug_lists)
06987       rsbac_printk(KERN_DEBUG "rsbac_ta_list_add_ttl: adding to list %s.\n",
06988              list->name);
06989 #endif
06990 */
06991     if(ttl && (ttl != RSBAC_LIST_TTL_KEEP))
06992       {
06993         if(ttl > RSBAC_LIST_MAX_AGE_LIMIT)
06994           ttl = RSBAC_LIST_MAX_AGE_LIMIT;
06995         ttl += RSBAC_CURRENT_TIME;
06996       }
06997     rsbac_write_lock(&list->lock, &lock_flags);
06998 
06999 #ifdef CONFIG_RSBAC_LIST_TRANS
07000     if(!ta_number)
07001 #endif
07002       {
07003         item_p = lookup_item(list, desc);
07004         if(item_p)
07005           { /* exists -> update data, if any */
07006             if(ttl != RSBAC_LIST_TTL_KEEP)
07007               item_p->max_age = ttl;
07008             if(data && list->info.data_size)
07009               {
07010                 if(   list->def_data
07011                    && !item_p->max_age
07012                    && !memcmp(list->def_data, data, list->info.data_size)
07013                   )
07014                   do_remove_item(list, item_p);
07015                 else
07016                   memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
07017                          data, list->info.data_size);
07018               }
07019           }
07020         else
07021           {
07022             if(ttl == RSBAC_LIST_TTL_KEEP)
07023               ttl = 0;
07024             if(   !list->def_data
07025                || memcmp(list->def_data, data, list->info.data_size)
07026               )
07027               add_item(list, ttl, desc, data);
07028           }
07029         touch(list);
07030         list->dirty = TRUE;
07031       }
07032 #ifdef CONFIG_RSBAC_LIST_TRANS
07033     if(   list->ta_copied
07034        || ta_number
07035       )
07036       {
07037         if(!list->ta_copied)
07038           ta_copy(ta_number, list);
07039         else
07040           if(ta_number)
07041             {
07042               if(list->ta_copied != ta_number)
07043                 {
07044                   rsbac_write_unlock(&list->lock, &lock_flags);
07045                   rsbac_read_unlock(&reg_head.lock, &rlock_flags);
07046                   return -RSBAC_EBUSY;
07047                 }
07048             }
07049           else
07050             ta_number = list->ta_copied;
07051         item_p = ta_lookup_item(ta_number, list, desc);
07052         if(item_p)
07053           { /* exists -> update data, if any */
07054             if(ttl != RSBAC_LIST_TTL_KEEP)
07055               item_p->max_age = ttl;
07056             if(data && list->info.data_size)
07057               {
07058                 if(   list->def_data
07059                    && !item_p->max_age
07060                    && !memcmp(list->def_data, data, list->info.data_size)
07061                   )
07062                   ta_do_remove_item(list, item_p);
07063                 else
07064                   memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
07065                          data, list->info.data_size);
07066               }
07067           }
07068         else
07069           {
07070             if(ttl == RSBAC_LIST_TTL_KEEP)
07071               ttl = 0;
07072             if(   !list->def_data
07073                || memcmp(list->def_data, data, list->info.data_size)
07074               )
07075               ta_add_item(ta_number, list, ttl, desc, data);
07076           }
07077       }
07078 #endif
07079     rsbac_write_unlock(&list->lock, &lock_flags);
07080     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
07081     return 0;
07082   }
07083 
07084 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07085 EXPORT_SYMBOL(rsbac_list_add_ttl);
07086 #endif
07087 int rsbac_list_add_ttl(
07088   rsbac_list_handle_t handle,
07089   rsbac_time_t ttl,
07090   void * desc,
07091   void * data)
07092   {
07093     return rsbac_ta_list_add_ttl(0, handle, ttl, desc, data);
07094   }
07095 
07096 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07097 EXPORT_SYMBOL(rsbac_list_add);
07098 #endif
07099 int rsbac_list_add(
07100   rsbac_list_handle_t handle,
07101   void * desc,
07102   void * data)
07103   {
07104     return rsbac_ta_list_add_ttl(0, handle, RSBAC_LIST_TTL_KEEP, desc, data);
07105   }
07106 
07107 /* add list of lists sublist item */
07108 /* if item for desc exists, the data is updated */
07109 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07110 EXPORT_SYMBOL(rsbac_ta_list_lol_subadd_ttl);
07111 #endif
07112 int rsbac_ta_list_lol_subadd_ttl(
07113   rsbac_list_ta_number_t ta_number,
07114   rsbac_list_handle_t handle,
07115   rsbac_time_t ttl,
07116   void * desc,
07117   void * subdesc,
07118   void * subdata)
07119   {
07120     struct rsbac_list_lol_reg_item_t * list;
07121     struct rsbac_list_lol_item_t     * sublist;
07122     struct rsbac_list_item_t     * item_p;
07123     u_long lock_flags, rlock_flags;
07124     int err = 0;
07125 
07126     if(!handle || !desc || !subdesc)
07127       return -RSBAC_EINVALIDVALUE;
07128     if(!list_initialized)
07129       return -RSBAC_ENOTINITIALIZED;
07130 
07131     list = (struct rsbac_list_lol_reg_item_t *) handle;
07132     if(!list || (list->self != list))
07133       return -RSBAC_EINVALIDVALUE;
07134 
07135 #ifdef CONFIG_RSBAC_LIST_TRANS
07136     if(ta_number && !rsbac_ta_list_exist(0, ta_handle, &ta_number))
07137       return -RSBAC_EINVALIDTRANSACTION;
07138 #endif
07139 
07140     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07141     if(list->info.subdata_size && !subdata)
07142       {
07143         rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07144         return -RSBAC_EINVALIDVALUE;
07145       }
07146 
07147 /*
07148 #ifdef CONFIG_RSBAC_DEBUG
07149     if(rsbac_debug_lists)
07150       rsbac_printk(KERN_DEBUG "rsbac_list_lol_subadd: adding to list %s.\n",
07151              list->name);
07152 #endif
07153 */
07154     rsbac_write_lock(&list->lock, &lock_flags);
07155 
07156 #ifdef CONFIG_RSBAC_LIST_TRANS
07157     if(!ta_number)
07158 #endif
07159       {
07160         sublist = lookup_lol_item(list, desc);
07161         if(   !sublist
07162            && (list->flags & RSBAC_LIST_DEF_DATA)
07163           )
07164           sublist = add_lol_item(list, 0, desc, list->def_data);
07165         if(sublist)
07166           {
07167             if(   sublist->max_age
07168                && (sublist->max_age <= RSBAC_CURRENT_TIME)
07169               )
07170               {
07171                 remove_lol_item(list, desc);
07172                 err = -RSBAC_EINVALIDTARGET;
07173               }
07174             else
07175               {
07176                 /* exists -> lookup subitem */
07177                 if(ttl && (ttl != RSBAC_LIST_TTL_KEEP))
07178                   {
07179                     if(ttl > RSBAC_LIST_MAX_AGE_LIMIT)
07180                       ttl = RSBAC_LIST_MAX_AGE_LIMIT;
07181                     ttl += RSBAC_CURRENT_TIME;
07182                   }
07183                 item_p = lookup_lol_subitem(list, sublist, subdesc);
07184                 if(item_p)
07185                   { /* exists -> update data, if any */
07186                     if(ttl != RSBAC_LIST_TTL_KEEP)
07187                       item_p->max_age = ttl;
07188                     if(subdata && list->info.subdata_size)
07189                       {
07190                         if(   list->def_subdata
07191                            && !item_p->max_age
07192                            && !memcmp(list->def_subdata, subdata, list->info.subdata_size)
07193                           )
07194                           do_remove_lol_subitem(sublist, item_p);
07195                         else
07196                           memcpy(((char *) item_p) + sizeof(*item_p) + list->info.subdesc_size,
07197                                  subdata,
07198                                  list->info.subdata_size);
07199                       }
07200                   }
07201                 else
07202                   {
07203                     if(ttl == RSBAC_LIST_TTL_KEEP)
07204                       ttl = 0;
07205                     if(   !list->def_subdata
07206                        || memcmp(list->def_subdata, subdata, list->info.subdata_size)
07207                       )
07208                       add_lol_subitem(list, sublist, ttl, subdesc, subdata);
07209                   }
07210                 lol_touch(list);
07211                 list->dirty = TRUE;
07212               }
07213           }
07214         else
07215           {
07216             err = -RSBAC_EINVALIDTARGET;
07217             goto out_unlock;
07218           }
07219       }
07220 #ifdef CONFIG_RSBAC_LIST_TRANS
07221     if(list->ta_copied || ta_number)
07222       {
07223         if(!list->ta_copied)
07224           {
07225             if((err = ta_lol_copy(ta_number,list)))
07226               goto out_unlock;
07227           }
07228         else
07229           if(ta_number)
07230             {
07231               if(list->ta_copied != ta_number)
07232                 {
07233                   err = -RSBAC_EBUSY;
07234                   goto out_unlock;
07235                 }
07236             }
07237           else
07238             ta_number = list->ta_copied;
07239         sublist = ta_lookup_lol_item(ta_number, list, desc);
07240         if(   !sublist
07241            && (list->flags & RSBAC_LIST_DEF_DATA)
07242           )
07243           sublist = ta_add_lol_item(ta_number, list, 0, desc, list->def_data);
07244         if(sublist)
07245           {
07246             if(   sublist->max_age
07247                && (sublist->max_age <= RSBAC_CURRENT_TIME)
07248               )
07249               {
07250                 ta_remove_lol_item(ta_number, list, desc);
07251                 err = -RSBAC_EINVALIDTARGET;
07252               }
07253             else
07254               {
07255                 /* exists -> lookup subitem */
07256                 if(ttl && (ttl != RSBAC_LIST_TTL_KEEP))
07257                   {
07258                     if(ttl > RSBAC_LIST_MAX_AGE_LIMIT)
07259                       ttl = RSBAC_LIST_MAX_AGE_LIMIT;
07260                     ttl += RSBAC_CURRENT_TIME;
07261                   }
07262                 item_p = lookup_lol_subitem(list, sublist, subdesc);
07263                 if(item_p)
07264                   { /* exists -> update data, if any */
07265                     if(ttl != RSBAC_LIST_TTL_KEEP)
07266                       item_p->max_age = ttl;
07267                     if(subdata && list->info.subdata_size)
07268                       {
07269                         if(   list->def_subdata
07270                            && !item_p->max_age
07271                            && !memcmp(list->def_subdata, subdata, list->info.subdata_size)
07272                           )
07273                           do_remove_lol_subitem(sublist, item_p);
07274                         else
07275                           memcpy(((char *) item_p) + sizeof(*item_p) + list->info.subdesc_size,
07276                                  subdata,
07277                                  list->info.subdata_size);
07278                       }
07279                   }
07280                 else
07281                   {
07282                     if(ttl == RSBAC_LIST_TTL_KEEP)
07283                       ttl = 0;
07284                     if(   !list->def_subdata
07285                        || memcmp(list->def_subdata, subdata, list->info.subdata_size)
07286                       )
07287                       add_lol_subitem(list, sublist, ttl, subdesc, subdata);
07288                   }
07289               }
07290           }
07291         else
07292           {
07293             err = -RSBAC_EINVALIDTARGET;
07294           }
07295       }
07296 #endif
07297 
07298 out_unlock:
07299     rsbac_write_unlock(&list->lock, &lock_flags);
07300     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07301     return err;
07302   }
07303 
07304 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07305 EXPORT_SYMBOL(rsbac_list_lol_subadd_ttl);
07306 #endif
07307 int rsbac_list_lol_subadd_ttl(
07308   rsbac_list_handle_t handle,
07309   rsbac_time_t ttl,
07310   void * desc,
07311   void * subdesc,
07312   void * subdata)
07313   {
07314     return rsbac_ta_list_lol_subadd_ttl(0, handle, ttl, desc, subdesc, subdata);
07315   }
07316 
07317 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07318 EXPORT_SYMBOL(rsbac_list_lol_subadd);
07319 #endif
07320 int rsbac_list_lol_subadd(
07321   rsbac_list_handle_t handle,
07322   void * desc,
07323   void * subdesc,
07324   void * subdata)
07325   {
07326     return rsbac_ta_list_lol_subadd_ttl(0, handle, RSBAC_LIST_TTL_KEEP, desc, subdesc, subdata);
07327   }
07328 
07329 /* add list of lists item */
07330 /* if item for desc exists, the data is updated */
07331 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07332 EXPORT_SYMBOL(rsbac_ta_list_lol_add_ttl);
07333 #endif
07334 int rsbac_ta_list_lol_add_ttl(
07335   rsbac_list_ta_number_t ta_number,
07336   rsbac_list_handle_t handle,
07337   rsbac_time_t ttl,
07338   void * desc,
07339   void * data)
07340   {
07341     struct rsbac_list_lol_reg_item_t * list;
07342     struct rsbac_list_lol_item_t     * item_p;
07343     u_long lock_flags, rlock_flags;
07344 
07345     if(!handle || !desc)
07346       return -RSBAC_EINVALIDVALUE;
07347     if(!list_initialized)
07348       return -RSBAC_ENOTINITIALIZED;
07349 
07350     list = (struct rsbac_list_lol_reg_item_t *) handle;
07351     if(!list || (list->self != list))
07352       return -RSBAC_EINVALIDVALUE;
07353 
07354 #ifdef CONFIG_RSBAC_LIST_TRANS
07355     if(ta_number && !rsbac_ta_list_exist(0, ta_handle, &ta_number))
07356       return -RSBAC_EINVALIDTRANSACTION;
07357 #endif
07358 
07359     if(ttl && (ttl != RSBAC_LIST_TTL_KEEP))
07360       {
07361         if(ttl > RSBAC_LIST_MAX_AGE_LIMIT)
07362           ttl = RSBAC_LIST_MAX_AGE_LIMIT;
07363         ttl += RSBAC_CURRENT_TIME;
07364       }
07365 
07366     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07367     if(list->info.data_size && !data)
07368       {
07369         rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07370         return -RSBAC_EINVALIDVALUE;
07371       }
07372 
07373 /*
07374 #ifdef CONFIG_RSBAC_DEBUG
07375     if(rsbac_debug_lists)
07376       rsbac_printk(KERN_DEBUG "rsbac_list_lol_add: adding to list %s.\n",
07377              list->name);
07378 #endif
07379 */
07380     rsbac_write_lock(&list->lock, &lock_flags);
07381 
07382 #ifdef CONFIG_RSBAC_LIST_TRANS
07383     if(!ta_number)
07384 #endif
07385       {
07386         item_p = lookup_lol_item(list, desc);
07387         if(item_p)
07388           { /* exists -> update data, if any */
07389             if(ttl != RSBAC_LIST_TTL_KEEP)
07390               item_p->max_age = ttl;
07391             if(data && list->info.data_size)
07392               {
07393                 if(   list->def_data
07394                    && !item_p->max_age
07395                    && !memcmp(list->def_data, data, list->info.data_size)
07396                    && !item_p->count
07397                   )
07398                   do_remove_lol_item(list, item_p);
07399                 else
07400                   memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
07401                          data, list->info.data_size);
07402               }
07403           }
07404         else
07405           {
07406             if(ttl == RSBAC_LIST_TTL_KEEP)
07407               ttl = 0;
07408             if(   !list->def_data
07409                || memcmp(list->def_data, data, list->info.data_size)
07410               )
07411               add_lol_item(list, ttl, desc, data);
07412           }
07413         lol_touch(list);
07414         list->dirty = TRUE;
07415       }
07416 #ifdef CONFIG_RSBAC_LIST_TRANS
07417     if(list->ta_copied || ta_number)
07418       {
07419         if(!list->ta_copied)
07420           ta_lol_copy(ta_number, list);
07421         else
07422           if(ta_number)
07423             {
07424               if(list->ta_copied != ta_number)
07425                 {
07426                   rsbac_write_unlock(&list->lock, &lock_flags);
07427                   rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07428                   return -RSBAC_EBUSY;
07429                 }
07430             }
07431           else
07432             ta_number = list->ta_copied;
07433         item_p = ta_lookup_lol_item(ta_number, list, desc);
07434         if(item_p)
07435           { /* exists -> update data, if any */
07436             if(ttl != RSBAC_LIST_TTL_KEEP)
07437               item_p->max_age = ttl;
07438             if(data && list->info.data_size)
07439               {
07440                 if(   list->def_data
07441                    && !item_p->max_age
07442                    && !memcmp(list->def_data, data, list->info.data_size)
07443                    && !item_p->count
07444                   )
07445                   ta_do_remove_lol_item(list, item_p);
07446                 else
07447                   memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
07448                          data, list->info.data_size);
07449               }
07450           }
07451         else
07452           {
07453             if(ttl == RSBAC_LIST_TTL_KEEP)
07454               ttl = 0;
07455             if(   !list->def_data
07456                || memcmp(list->def_data, data, list->info.data_size)
07457               )
07458               ta_add_lol_item(ta_number, list, ttl, desc, data);
07459           }
07460       }
07461 #endif
07462     rsbac_write_unlock(&list->lock, &lock_flags);
07463     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07464     return 0;
07465   }
07466 
07467 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07468 EXPORT_SYMBOL(rsbac_list_lol_add_ttl);
07469 #endif
07470 int rsbac_list_lol_add_ttl(
07471   rsbac_list_handle_t handle,
07472   rsbac_time_t ttl,
07473   void * desc,
07474   void * data)
07475   {
07476     return rsbac_ta_list_lol_add_ttl(0, handle, ttl, desc, data);
07477   }
07478 
07479 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07480 EXPORT_SYMBOL(rsbac_list_lol_add);
07481 #endif
07482 int rsbac_list_lol_add(
07483   rsbac_list_handle_t handle,
07484   void * desc,
07485   void * data)
07486   {
07487     return rsbac_ta_list_lol_add_ttl(0, handle, RSBAC_LIST_TTL_KEEP, desc, data);
07488   }
07489 
07490 /* remove item */
07491 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07492 EXPORT_SYMBOL(rsbac_ta_list_remove);
07493 #endif
07494 int rsbac_ta_list_remove(
07495   rsbac_list_ta_number_t ta_number,
07496   rsbac_list_handle_t handle,
07497   void * desc)
07498   {
07499     struct rsbac_list_reg_item_t * list;
07500     u_long lock_flags, rlock_flags;
07501 
07502     if(!handle || !desc)
07503       return -RSBAC_EINVALIDVALUE;
07504     if(!list_initialized)
07505       return -RSBAC_ENOTINITIALIZED;
07506 
07507     list = (struct rsbac_list_reg_item_t *) handle;
07508     if(!list || (list->self != list))
07509       return -RSBAC_EINVALIDVALUE;
07510 
07511 #ifdef CONFIG_RSBAC_LIST_TRANS
07512     if(ta_number)
07513       {
07514         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07515           return -RSBAC_EINVALIDTRANSACTION;
07516       }
07517 #endif
07518 
07519     rsbac_read_lock(&reg_head.lock, &rlock_flags);
07520 /*
07521 #ifdef CONFIG_RSBAC_DEBUG
07522     if(rsbac_debug_lists)
07523       rsbac_printk(KERN_DEBUG "rsbac_list_ta_remove: removing from list %s.\n",
07524              list->name);
07525 #endif
07526 */
07527     rsbac_write_lock(&list->lock, &lock_flags);
07528 #ifdef CONFIG_RSBAC_LIST_TRANS
07529     if(list->ta_copied)
07530       {
07531         if(ta_number)
07532           {
07533             if(ta_lookup_item(list->ta_copied, list, desc))
07534               {
07535                 if(list->ta_copied != ta_number)
07536                   {
07537                     rsbac_write_unlock(&list->lock, &lock_flags);
07538                     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
07539                     return -RSBAC_EBUSY;
07540                   }
07541                 else
07542                   ta_remove_item(ta_number, list, desc);
07543               }
07544           }
07545         else
07546           ta_remove_item(list->ta_copied, list, desc);
07547       }
07548     else
07549       {
07550         if(ta_number && lookup_item(list, desc))
07551           {
07552             ta_copy(ta_number, list);
07553             ta_remove_item(ta_number, list, desc);
07554           }
07555       }
07556     if(!ta_number)
07557 #endif
07558       {
07559         if(lookup_item(list, desc))
07560           { /* exists -> remove */
07561             remove_item(list, desc);
07562             touch(list);
07563             list->dirty = TRUE;
07564           }
07565       }
07566     rsbac_write_unlock(&list->lock, &lock_flags);
07567     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
07568     return 0;
07569   }
07570 
07571 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07572 EXPORT_SYMBOL(rsbac_list_remove);
07573 #endif
07574 int rsbac_list_remove(
07575   rsbac_list_handle_t handle,
07576   void * desc)
07577   {
07578     return rsbac_ta_list_remove(0, handle, desc);
07579   }
07580 
07581 /* remove all items */
07582 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07583 EXPORT_SYMBOL(rsbac_ta_list_remove_all);
07584 #endif
07585 int rsbac_ta_list_remove_all(rsbac_list_ta_number_t ta_number, rsbac_list_handle_t handle)
07586   {
07587     struct rsbac_list_reg_item_t * list;
07588     u_long lock_flags, rlock_flags;
07589 
07590     if(!handle)
07591       return -RSBAC_EINVALIDVALUE;
07592     if(!list_initialized)
07593       return -RSBAC_ENOTINITIALIZED;
07594 
07595     list = (struct rsbac_list_reg_item_t *) handle;
07596     if(list->self != list)
07597       return -RSBAC_EINVALIDVALUE;
07598 
07599 #ifdef CONFIG_RSBAC_LIST_TRANS
07600     if(ta_number)
07601       {
07602         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07603           return -RSBAC_EINVALIDTRANSACTION;
07604       }
07605 #endif
07606 
07607     rsbac_read_lock(&reg_head.lock, &rlock_flags);
07608 /*
07609 #ifdef CONFIG_RSBAC_DEBUG
07610     if(rsbac_debug_lists)
07611       rsbac_printk(KERN_DEBUG "rsbac_ta_list_remove_all: removing all items from list %s.\n",
07612              list->name);
07613 #endif
07614 */
07615     rsbac_write_lock(&list->lock, &lock_flags);
07616 #ifdef CONFIG_RSBAC_LIST_TRANS
07617     if(list->ta_copied)
07618       {
07619         if(ta_number)
07620           {
07621             if(list->ta_copied == ta_number)
07622               {
07623                 ta_remove_all_items(list);
07624                 if(!list->head)
07625                   {
07626                     list->ta_copied = 0;
07627                   }
07628               }
07629             else
07630               {
07631                 rsbac_write_unlock(&list->lock, &lock_flags);
07632                 rsbac_read_unlock(&reg_head.lock, &rlock_flags);
07633                 return -RSBAC_EBUSY;
07634               }
07635           }
07636         else
07637           ta_remove_all_items(list);
07638       }
07639     else
07640       {
07641         if(ta_number)
07642           {
07643             if(list->head)
07644               {
07645                 list->ta_head = NULL;
07646                 list->ta_tail = NULL;
07647                 list->ta_curr = NULL;
07648                 list->ta_count = 0;
07649                 list->ta_copied = ta_number;
07650               }
07651           }
07652       }
07653 
07654     if(!ta_number)
07655 #endif
07656       if(list->head)
07657         {
07658           remove_all_items(list);
07659           touch(list);
07660           list->dirty = TRUE;
07661         }
07662     rsbac_write_unlock(&list->lock, &lock_flags);
07663     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
07664     return 0;
07665   }
07666 
07667 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07668 EXPORT_SYMBOL(rsbac_list_remove_all);
07669 #endif
07670 int rsbac_list_remove_all(rsbac_list_handle_t handle)
07671   {
07672     return rsbac_ta_list_remove_all(0, handle);
07673   }
07674 
07675 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07676 EXPORT_SYMBOL(rsbac_ta_list_lol_subremove);
07677 #endif
07678 int rsbac_ta_list_lol_subremove(
07679   rsbac_list_ta_number_t ta_number,
07680   rsbac_list_handle_t handle,
07681   void * desc,
07682   void * subdesc)
07683   {
07684     struct rsbac_list_lol_reg_item_t * list;
07685     struct rsbac_list_lol_item_t     * sublist;
07686     u_long lock_flags, rlock_flags;
07687 
07688     if(!handle || !desc || !subdesc)
07689       return -RSBAC_EINVALIDVALUE;
07690     if(!list_initialized)
07691       return -RSBAC_ENOTINITIALIZED;
07692 
07693     list = (struct rsbac_list_lol_reg_item_t *) handle;
07694     if(list->self != list)
07695       return -RSBAC_EINVALIDVALUE;
07696 
07697 #ifdef CONFIG_RSBAC_LIST_TRANS
07698     if(ta_number)
07699       {
07700         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07701           return -RSBAC_EINVALIDTRANSACTION;
07702       }
07703 #endif
07704 
07705     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07706 /*
07707 #ifdef CONFIG_RSBAC_DEBUG
07708     if(rsbac_debug_lists)
07709       rsbac_printk(KERN_DEBUG "rsbac_ta_list_lol_subremove: removing from list of lists %s, device %02u:%02u.\n",
07710              list->name,
07711              RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device));
07712 #endif
07713 */
07714     rsbac_write_lock(&list->lock, &lock_flags);
07715 #ifdef CONFIG_RSBAC_LIST_TRANS
07716     if(list->ta_copied)
07717       {
07718         sublist = ta_lookup_lol_item(list->ta_copied, list, desc);
07719         if(sublist)
07720           {
07721             if(   sublist->max_age
07722                && (sublist->max_age <= RSBAC_CURRENT_TIME)
07723               )
07724               {
07725                 ta_do_remove_lol_item(list, sublist);
07726               }
07727             else
07728               {
07729                 if(ta_number && (list->ta_copied != ta_number))
07730                   {
07731                     rsbac_write_unlock(&list->lock, &lock_flags);
07732                     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07733                     return -RSBAC_EBUSY;
07734                   }
07735                 if(lookup_lol_subitem(list, sublist, subdesc))
07736                   remove_lol_subitem(list, sublist, subdesc);
07737                 if(   !sublist->count
07738                    && (   (   list->def_data
07739                            && !memcmp(((char *) sublist) + sizeof(*sublist) + list->info.desc_size,
07740                                       list->def_data,
07741                                       list->info.data_size)
07742                           )
07743                        || (   !list->info.data_size
07744                            && (list->flags & RSBAC_LIST_DEF_DATA)
07745                           )
07746                       )
07747                       )
07748                   {
07749                     ta_do_remove_lol_item(list, sublist);
07750                   }
07751               }
07752           }
07753       }
07754     else
07755       {
07756         if(ta_number && lookup_lol_item(list, desc))
07757           {
07758             ta_lol_copy(ta_number, list);
07759             ta_remove_lol_item(ta_number, list, desc);
07760           }
07761       }
07762     if(!ta_number)
07763 #endif
07764       {
07765         sublist = lookup_lol_item(list, desc);
07766         if(sublist)
07767           {
07768             if(   sublist->max_age
07769                && (sublist->max_age <= RSBAC_CURRENT_TIME)
07770               )
07771               {
07772                 do_remove_lol_item(list, sublist);
07773                 lol_touch(list);
07774                 list->dirty = TRUE;
07775               }
07776             else
07777               {
07778                 if(lookup_lol_subitem(list, sublist, subdesc))
07779                   { /* exists -> remove and set dirty */
07780                     remove_lol_subitem(list, sublist, subdesc);
07781                     lol_touch(list);
07782                     list->dirty = TRUE;
07783                   }
07784                 if(   !sublist->count
07785                    && (   (   list->def_data
07786                            && !memcmp(((char *) sublist) + sizeof(*sublist) + list->info.desc_size,
07787                                       list->def_data,
07788                                       list->info.data_size)
07789                           )
07790                        || (   !list->info.data_size
07791                            && (list->flags & RSBAC_LIST_DEF_DATA)
07792                           )
07793                       )
07794                   )
07795                   {
07796                     do_remove_lol_item(list, sublist);
07797                     lol_touch(list);
07798                     list->dirty = TRUE;
07799                   }
07800               }
07801           }
07802       }
07803     rsbac_write_unlock(&list->lock, &lock_flags);
07804     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07805     return 0;
07806   }
07807 
07808 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07809 EXPORT_SYMBOL(rsbac_list_lol_subremove);
07810 #endif
07811 int rsbac_list_lol_subremove(
07812   rsbac_list_handle_t handle,
07813   void * desc,
07814   void * subdesc)
07815   {
07816     return rsbac_ta_list_lol_subremove(0, handle, desc, subdesc);
07817   }
07818 
07819 /* remove same subitem from all items */
07820 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07821 EXPORT_SYMBOL(rsbac_ta_list_lol_subremove_from_all);
07822 #endif
07823 int rsbac_ta_list_lol_subremove_from_all(
07824   rsbac_list_ta_number_t ta_number,
07825   rsbac_list_handle_t handle,
07826   void * subdesc)
07827   {
07828     struct rsbac_list_lol_reg_item_t * list;
07829     struct rsbac_list_lol_item_t     * sublist;
07830     u_long lock_flags, rlock_flags;
07831 
07832     if(!handle || !subdesc)
07833       return -RSBAC_EINVALIDVALUE;
07834     if(!list_initialized)
07835       return -RSBAC_ENOTINITIALIZED;
07836 
07837     list = (struct rsbac_list_lol_reg_item_t *) handle;
07838     if(list->self != list)
07839       return -RSBAC_EINVALIDVALUE;
07840 
07841 #ifdef CONFIG_RSBAC_LIST_TRANS
07842     if(ta_number)
07843       {
07844         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07845           return -RSBAC_EINVALIDTRANSACTION;
07846       }
07847 #endif
07848 
07849     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07850 /*
07851 #ifdef CONFIG_RSBAC_DEBUG
07852     if(rsbac_debug_lists)
07853       rsbac_printk(KERN_DEBUG "rsbac_list_lol_subremove_from_all: removing from list of lists %s.\n",
07854              list->name);
07855 #endif
07856 */
07857     rsbac_write_lock(&list->lock, &lock_flags);
07858 #ifdef CONFIG_RSBAC_LIST_TRANS
07859     if(list->ta_copied)
07860       {
07861         if(ta_number && (list->ta_copied != ta_number))
07862           {
07863             rsbac_write_unlock(&list->lock, &lock_flags);
07864             rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07865             return -RSBAC_EBUSY;
07866           }
07867         sublist = list->head;
07868         while(sublist)
07869           {
07870             remove_lol_subitem(list, sublist, subdesc);
07871             sublist = sublist->next;
07872           }
07873       }
07874     else
07875       {
07876         if(ta_number)
07877           {
07878             ta_lol_copy(ta_number, list);
07879             sublist = list->head;
07880             while(sublist)
07881               {
07882                 remove_lol_subitem(list, sublist, subdesc);
07883                 sublist = sublist->next;
07884               }
07885           }
07886       }
07887     if(!ta_number)
07888 #endif
07889       {
07890         sublist = list->head;
07891         while(sublist)
07892           {
07893             if(lookup_lol_subitem(list, sublist, subdesc))
07894               { /* exists -> remove and set dirty */
07895                 remove_lol_subitem(list, sublist, subdesc);
07896                 lol_touch(list);
07897                 list->dirty = TRUE;
07898               }
07899             sublist = sublist->next;
07900           }
07901       }
07902     rsbac_write_unlock(&list->lock, &lock_flags);
07903     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07904     return 0;
07905   }
07906 
07907 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07908 EXPORT_SYMBOL(rsbac_list_lol_subremove_from_all);
07909 #endif
07910 int rsbac_list_lol_subremove_from_all(
07911   rsbac_list_handle_t handle,
07912   void * subdesc)
07913   {
07914     return rsbac_ta_list_lol_subremove_from_all(0, handle, subdesc);
07915   }
07916 
07917 /* remove all subitems */
07918 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07919 EXPORT_SYMBOL(rsbac_ta_list_lol_subremove_all);
07920 #endif
07921 int rsbac_ta_list_lol_subremove_all(
07922   rsbac_list_ta_number_t ta_number,
07923   rsbac_list_handle_t handle,
07924   void * desc)
07925   {
07926     struct rsbac_list_lol_reg_item_t * list;
07927     struct rsbac_list_lol_item_t     * sublist;
07928     u_long lock_flags, rlock_flags;
07929 
07930     if(!handle)
07931       return -RSBAC_EINVALIDVALUE;
07932     if(!list_initialized)
07933       return -RSBAC_ENOTINITIALIZED;
07934 
07935     list = (struct rsbac_list_lol_reg_item_t *) handle;
07936     if(list->self != list)
07937       return -RSBAC_EINVALIDVALUE;
07938 
07939 #ifdef CONFIG_RSBAC_LIST_TRANS
07940     if(ta_number)
07941       {
07942         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07943           return -RSBAC_EINVALIDTRANSACTION;
07944       }
07945 #endif
07946 
07947     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07948 /*
07949 #ifdef CONFIG_RSBAC_DEBUG
07950     if(rsbac_debug_lists)
07951       rsbac_printk(KERN_DEBUG "rsbac_list_lol_subremove_all: removing all subitems from list of lists %s.\n",
07952              list->name);
07953 #endif
07954 */
07955     rsbac_write_lock(&list->lock, &lock_flags);
07956 #ifdef CONFIG_RSBAC_LIST_TRANS
07957     if(list->ta_copied)
07958       {
07959         sublist = ta_lookup_lol_item(list->ta_copied, list, desc);
07960         if(sublist)
07961           {
07962             if(   sublist->max_age
07963                && (sublist->max_age <= RSBAC_CURRENT_TIME)
07964               )
07965               {
07966                 ta_do_remove_lol_item(list, sublist);
07967               }
07968             else
07969               {
07970                 if(ta_number && (list->ta_copied != ta_number))
07971                   {
07972                     rsbac_write_unlock(&list->lock, &lock_flags);
07973                     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07974                     return -RSBAC_EBUSY;
07975                   }
07976                 remove_all_lol_subitems(sublist);
07977                 if(   (   list->def_data
07978                        && !memcmp(((char *) sublist) + sizeof(*sublist) + list->info.desc_size,
07979                                   list->def_data,
07980                                   list->info.data_size)
07981                       )
07982                    || (   !list->info.data_size
07983                        && (list->flags & RSBAC_LIST_DEF_DATA)
07984                       )
07985                    
07986                   )
07987                   {
07988                     ta_do_remove_lol_item(list, sublist);
07989                   }
07990               }
07991           }
07992       }
07993     else
07994       {
07995         if(ta_number && lookup_lol_item(list, desc))
07996           {
07997             ta_lol_copy(ta_number, list);
07998             sublist = ta_lookup_lol_item(ta_number, list, desc);
07999             if(sublist)
08000               remove_all_lol_subitems(sublist);
08001           }
08002       }
08003     if(!ta_number)
08004 #endif
08005       {
08006         sublist = lookup_lol_item(list, desc);
08007         if(sublist && sublist->head)
08008           {
08009             remove_all_lol_subitems(sublist);
08010             lol_touch(list);
08011             list->dirty = TRUE;
08012           }
08013       }
08014     rsbac_write_unlock(&list->lock, &lock_flags);
08015     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08016     return 0;
08017   }
08018 
08019 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08020 EXPORT_SYMBOL(rsbac_list_lol_subremove_all);
08021 #endif
08022 int rsbac_list_lol_subremove_all(rsbac_list_handle_t handle, void * desc)
08023   {
08024     return rsbac_ta_list_lol_subremove_all(0, handle, desc);
08025   }
08026 
08027 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08028 EXPORT_SYMBOL(rsbac_ta_list_lol_remove);
08029 #endif
08030 int rsbac_ta_list_lol_remove(
08031   rsbac_list_ta_number_t ta_number,
08032   rsbac_list_handle_t handle,
08033   void * desc)
08034   {
08035     struct rsbac_list_lol_reg_item_t * list;
08036     u_long lock_flags, rlock_flags;
08037 
08038     if(!handle || !desc)
08039       return -RSBAC_EINVALIDVALUE;
08040     if(!list_initialized)
08041       return -RSBAC_ENOTINITIALIZED;
08042 
08043     list = (struct rsbac_list_lol_reg_item_t *) handle;
08044     if(list->self != list)
08045       return -RSBAC_EINVALIDVALUE;
08046 
08047 #ifdef CONFIG_RSBAC_LIST_TRANS
08048     if(ta_number)
08049       {
08050         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08051           return -RSBAC_EINVALIDTRANSACTION;
08052       }
08053 #endif
08054 
08055     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08056 /*
08057 #ifdef CONFIG_RSBAC_DEBUG
08058     if(rsbac_debug_lists)
08059       rsbac_printk(KERN_DEBUG "rsbac_list_lol_remove: removing from list of lists %s.\n",
08060              list->name);
08061 #endif
08062 */
08063     rsbac_write_lock(&list->lock, &lock_flags);
08064 #ifdef CONFIG_RSBAC_LIST_TRANS
08065     if(list->ta_copied)
08066       {
08067         if(ta_number)
08068           {
08069             if(ta_lookup_lol_item(list->ta_copied, list, desc))
08070               {
08071                 if(list->ta_copied != ta_number)
08072                   {
08073                     rsbac_write_unlock(&list->lock, &lock_flags);
08074                     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08075                     return -RSBAC_EBUSY;
08076                   }
08077                 else
08078                   ta_remove_lol_item(ta_number, list, desc);
08079               }
08080           }
08081         else
08082           ta_remove_lol_item(list->ta_copied, list, desc);
08083       }
08084     else
08085       {
08086         if(ta_number && lookup_lol_item(list, desc))
08087           {
08088             ta_lol_copy(ta_number, list);
08089             ta_remove_lol_item(ta_number, list, desc);
08090           }
08091       }
08092     if(!ta_number)
08093 #endif
08094       {
08095         if(lookup_lol_item(list, desc))
08096           { /* exists -> remove */
08097             remove_lol_item(list, desc);
08098             lol_touch(list);
08099             list->dirty = TRUE;
08100           }
08101       }
08102     rsbac_write_unlock(&list->lock, &lock_flags);
08103     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08104     return 0;
08105   }
08106 
08107 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08108 EXPORT_SYMBOL(rsbac_list_lol_remove);
08109 #endif
08110 int rsbac_list_lol_remove(
08111   rsbac_list_handle_t handle,
08112   void * desc)
08113   {
08114     return rsbac_ta_list_lol_remove(0, handle, desc);
08115   }
08116 
08117 /* remove all items */
08118 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08119 EXPORT_SYMBOL(rsbac_ta_list_lol_remove_all);
08120 #endif
08121 int rsbac_ta_list_lol_remove_all(rsbac_list_ta_number_t ta_number, rsbac_list_handle_t handle)
08122   {
08123     struct rsbac_list_lol_reg_item_t * list;
08124     u_long lock_flags, rlock_flags;
08125 
08126     if(!handle)
08127       return -RSBAC_EINVALIDVALUE;
08128     if(!list_initialized)
08129       return -RSBAC_ENOTINITIALIZED;
08130 
08131     list = (struct rsbac_list_lol_reg_item_t *) handle;
08132     if(list->self != list)
08133       return -RSBAC_EINVALIDVALUE;
08134 
08135 #ifdef CONFIG_RSBAC_LIST_TRANS
08136     if(ta_number)
08137       {
08138         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08139           return -RSBAC_EINVALIDTRANSACTION;
08140       }
08141 #endif
08142 
08143     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08144 /*
08145 #ifdef CONFIG_RSBAC_DEBUG
08146     if(rsbac_debug_lists)
08147       rsbac_printk(KERN_DEBUG "rsbac_list_lol_remove_all: removing all items from list of lists %s.\n",
08148              list->name);
08149 #endif
08150 */
08151     rsbac_write_lock(&list->lock, &lock_flags);
08152 #ifdef CONFIG_RSBAC_LIST_TRANS
08153     if(list->ta_copied)
08154       {
08155         if(ta_number)
08156           {
08157             if(list->ta_copied == ta_number)
08158               {
08159                 ta_remove_all_lol_items(list);
08160                 if(!list->head)
08161                   {
08162                     list->ta_copied = 0;
08163                   }
08164               }
08165             else
08166               {
08167                 rsbac_write_unlock(&list->lock, &lock_flags);
08168                 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08169                 return -RSBAC_EBUSY;
08170               }
08171           }
08172         else
08173           ta_remove_all_lol_items(list);
08174       }
08175     else
08176       {
08177         if(ta_number)
08178           {
08179             if(list->head)
08180               {
08181                 list->ta_head = NULL;
08182                 list->ta_tail = NULL;
08183                 list->ta_curr = NULL;
08184                 list->ta_count = 0;
08185                 list->ta_copied = ta_number;
08186               }
08187           }
08188       }
08189 
08190     if(!ta_number)
08191 #endif
08192       if(list->head)
08193         {
08194           remove_all_lol_items(list);
08195           lol_touch(list);
08196           list->dirty = TRUE;
08197         }
08198     rsbac_write_unlock(&list->lock, &lock_flags);
08199     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08200     return 0;
08201   }
08202 
08203 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08204 EXPORT_SYMBOL(rsbac_list_lol_remove_all);
08205 #endif
08206 int rsbac_list_lol_remove_all(rsbac_list_handle_t handle)
08207   {
08208     return rsbac_ta_list_lol_remove_all(0, handle);
08209   }
08210 
08211 /* get item data */
08212 /* Item data is copied - we cannot give a pointer, because item could be
08213  * removed */
08214 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08215 EXPORT_SYMBOL(rsbac_ta_list_get_data_ttl);
08216 #endif
08217 int rsbac_ta_list_get_data_ttl(
08218   rsbac_list_ta_number_t ta_number,
08219   rsbac_list_handle_t handle,
08220   rsbac_time_t * ttl_p,
08221   void * desc,
08222   void * data)
08223   {
08224     struct rsbac_list_reg_item_t * list;
08225     struct rsbac_list_item_t     * item_p;
08226     u_long lock_flags, rlock_flags;
08227     int err = 0;
08228 
08229     if(!handle || !desc)
08230       return -RSBAC_EINVALIDVALUE;
08231     if(!list_initialized)
08232       return -RSBAC_ENOTINITIALIZED;
08233 
08234     list = (struct rsbac_list_reg_item_t *) handle;
08235     if(list->self != list)
08236       return -RSBAC_EINVALIDVALUE;
08237 
08238 #ifdef CONFIG_RSBAC_LIST_TRANS
08239     if(ta_number)
08240       {
08241         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08242           return -RSBAC_EINVALIDTRANSACTION;
08243       }
08244 #endif
08245 
08246     rsbac_read_lock(&reg_head.lock, &rlock_flags);
08247 /*
08248 #ifdef CONFIG_RSBAC_DEBUG
08249     if(rsbac_debug_lists)
08250       rsbac_printk(KERN_DEBUG "rsbac_list_get_data: getting data from list %s.\n",
08251              list->name);
08252 #endif
08253 */
08254     if(data && !list->info.data_size)
08255       {
08256         rsbac_read_unlock(&reg_head.lock, &rlock_flags);
08257         return -RSBAC_EINVALIDREQUEST;
08258       }
08259 
08260     rsbac_read_lock(&list->lock, &lock_flags);
08261 #ifdef CONFIG_RSBAC_LIST_TRANS
08262     if(ta_number && (list->ta_copied == ta_number))
08263       item_p = ta_lookup_item(ta_number, list, desc);
08264     else
08265 #endif
08266       item_p = lookup_item(list, desc);
08267     if(   item_p
08268        && (   !item_p->max_age
08269            || (item_p->max_age > RSBAC_CURRENT_TIME)
08270           )
08271       )
08272       { /* exists -> copy data, if any */
08273         if(ttl_p)
08274           {
08275             if(item_p->max_age)
08276               *ttl_p = item_p->max_age - RSBAC_CURRENT_TIME;
08277             else
08278               *ttl_p = 0;
08279           }
08280         if(data)
08281           {
08282             memcpy(data,
08283                    ((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
08284                    list->info.data_size);
08285           }
08286       }
08287     else
08288       {
08289         if(!list->def_data)
08290           err = -RSBAC_ENOTFOUND;
08291         else
08292           {
08293             if(ttl_p)
08294               *ttl_p = 0;
08295             if(data)
08296               memcpy(data,
08297                      list->def_data,
08298                      list->info.data_size);
08299           }
08300       }
08301     rsbac_read_unlock(&list->lock, &lock_flags);
08302     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
08303     return err;
08304   }
08305 
08306 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08307 EXPORT_SYMBOL(rsbac_list_get_data_ttl);
08308 #endif
08309 int rsbac_list_get_data_ttl(rsbac_list_handle_t handle,
08310                             rsbac_time_t * ttl_p,
08311                             void * desc,
08312                             void * data)
08313   {
08314     return rsbac_ta_list_get_data_ttl(0, handle, ttl_p, desc, data);
08315   }
08316 
08317 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08318 EXPORT_SYMBOL(rsbac_list_get_data);
08319 #endif
08320 int rsbac_list_get_data(rsbac_list_handle_t handle, void * desc, void * data)
08321   {
08322     return rsbac_ta_list_get_data_ttl(0, handle, NULL, desc, data);
08323   }
08324 
08325 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08326 EXPORT_SYMBOL(rsbac_ta_list_lol_get_subdata_ttl);
08327 #endif
08328 int rsbac_ta_list_lol_get_subdata_ttl(
08329   rsbac_list_ta_number_t ta_number,
08330   rsbac_list_handle_t handle,
08331   rsbac_time_t * ttl_p,
08332   void * desc,
08333   void * subdesc,
08334   void * subdata)
08335   {
08336     struct rsbac_list_lol_reg_item_t * list;
08337     struct rsbac_list_lol_item_t     * sublist;
08338     struct rsbac_list_item_t         * item_p;
08339     u_long lock_flags, rlock_flags;
08340     int err = 0;
08341 
08342     if(!handle || !desc || !subdesc)
08343       return -RSBAC_EINVALIDVALUE;
08344     if(!list_initialized)
08345       return -RSBAC_ENOTINITIALIZED;
08346 
08347     list = (struct rsbac_list_lol_reg_item_t *) handle;
08348     if(list->self != list)
08349       return -RSBAC_EINVALIDVALUE;
08350 
08351 #ifdef CONFIG_RSBAC_LIST_TRANS
08352     if(ta_number)
08353       {
08354         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08355           return -RSBAC_EINVALIDTRANSACTION;
08356       }
08357 #endif
08358 
08359     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08360 /*
08361 #ifdef CONFIG_RSBAC_DEBUG
08362     if(rsbac_debug_lists)
08363       rsbac_printk(KERN_DEBUG "rsbac_list_lol_get_subdata: getting data from list %s.\n",
08364              list->name);
08365 #endif
08366 */
08367     if(subdata && !list->info.subdata_size)
08368       {
08369         rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08370         return -RSBAC_EINVALIDREQUEST;
08371       }
08372 
08373     rsbac_read_lock(&list->lock, &lock_flags);
08374 
08375 #ifdef CONFIG_RSBAC_LIST_TRANS
08376     if(ta_number && (list->ta_copied == ta_number))
08377       sublist = ta_lookup_lol_item(ta_number, list, desc);
08378     else
08379 #endif
08380     sublist = lookup_lol_item(list, desc);
08381     if(sublist)
08382       { /* exists -> lookup subitem */
08383         item_p = lookup_lol_subitem(list, sublist, subdesc);
08384         if(   item_p
08385            && (   !item_p->max_age
08386                || (item_p->max_age > RSBAC_CURRENT_TIME)
08387               )
08388           )
08389           { /* exists -> copy data, if any */
08390             if(ttl_p)
08391               {
08392                 if(item_p->max_age)
08393                   *ttl_p = item_p->max_age - RSBAC_CURRENT_TIME;
08394                 else
08395                   *ttl_p = 0;
08396               }
08397             if(subdata)
08398               {
08399                 memcpy(subdata,
08400                        ((char *) item_p) + sizeof(*item_p) + list->info.subdesc_size,
08401                        list->info.subdata_size);
08402               }
08403           }
08404         else
08405           {
08406             if(!list->def_subdata)
08407               err = -RSBAC_ENOTFOUND;
08408             else
08409               {
08410                 if(ttl_p)
08411                   *ttl_p = 0;
08412                 if(subdata)
08413                   memcpy(subdata,
08414                          list->def_subdata,
08415                          list->info.subdata_size);
08416               }
08417           }
08418       }
08419     else
08420       {
08421         if(!list->def_subdata)
08422           err = -RSBAC_ENOTFOUND;
08423         else
08424           {
08425             if(ttl_p)
08426               *ttl_p = 0;
08427             if(subdata)
08428               memcpy(subdata,
08429                      list->def_subdata,
08430                      list->info.subdata_size);
08431           }
08432       }
08433     rsbac_read_unlock(&list->lock, &lock_flags);
08434     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08435     return err;
08436   }
08437 
08438 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08439 EXPORT_SYMBOL(rsbac_list_lol_get_subdata_ttl);
08440 #endif
08441 int rsbac_list_lol_get_subdata_ttl(
08442   rsbac_list_handle_t handle,
08443   rsbac_time_t * ttl_p,
08444   void * desc,
08445   void * subdesc,
08446   void * subdata)
08447   {
08448     return rsbac_ta_list_lol_get_subdata_ttl(0, handle,
08449                                              ttl_p, desc, subdesc, subdata);
08450   }
08451 
08452 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08453 EXPORT_SYMBOL(rsbac_list_lol_get_subdata);
08454 #endif
08455 int rsbac_list_lol_get_subdata(
08456   rsbac_list_handle_t handle,
08457   void * desc,
08458   void * subdesc,
08459   void * subdata)
08460   {
08461     return rsbac_ta_list_lol_get_subdata_ttl(0, handle, NULL, desc, subdesc, subdata);
08462   }
08463 
08464 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08465 EXPORT_SYMBOL(rsbac_ta_list_lol_get_data_ttl);
08466 #endif
08467 int rsbac_ta_list_lol_get_data_ttl(
08468   rsbac_list_ta_number_t ta_number,
08469   rsbac_list_handle_t handle,
08470   rsbac_time_t * ttl_p,
08471   void * desc,
08472   void * data)
08473   {
08474     struct rsbac_list_lol_reg_item_t * list;
08475     struct rsbac_list_lol_item_t     * item_p;
08476     u_long lock_flags, rlock_flags;
08477     int err = 0;
08478 
08479     if(!handle || !desc)
08480       return -RSBAC_EINVALIDVALUE;
08481     if(!list_initialized)
08482       return -RSBAC_ENOTINITIALIZED;
08483 
08484     list = (struct rsbac_list_lol_reg_item_t *) handle;
08485     if(list->self != list)
08486       return -RSBAC_EINVALIDVALUE;
08487 
08488 #ifdef CONFIG_RSBAC_LIST_TRANS
08489     if(ta_number)
08490       {
08491         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08492           return -RSBAC_EINVALIDTRANSACTION;
08493       }
08494 #endif
08495 
08496     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08497 /*
08498 #ifdef CONFIG_RSBAC_DEBUG
08499     if(rsbac_debug_lists)
08500       rsbac_printk(KERN_DEBUG "rsbac_list_lol_get_data: getting data from list %s.\n",
08501              list->name);
08502 #endif
08503 */
08504     if(data && !list->info.data_size)
08505       {
08506         rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08507         return -RSBAC_EINVALIDREQUEST;
08508       }
08509 
08510     rsbac_read_lock(&list->lock, &lock_flags);
08511 
08512 #ifdef CONFIG_RSBAC_LIST_TRANS
08513     if(ta_number && (list->ta_copied == ta_number))
08514       item_p = ta_lookup_lol_item(ta_number, list, desc);
08515     else
08516 #endif
08517     item_p = lookup_lol_item(list, desc);
08518     if(   item_p
08519        && (   !item_p->max_age
08520            || (item_p->max_age > RSBAC_CURRENT_TIME)
08521           )
08522       )
08523       { /* exists -> copy data, if any */
08524         if(ttl_p)
08525           {
08526             if(item_p->max_age)
08527               *ttl_p = item_p->max_age - RSBAC_CURRENT_TIME;
08528             else
08529               *ttl_p = 0;
08530           }
08531         if(data)
08532           {
08533             memcpy(data,
08534                    ((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
08535                    list->info.data_size);
08536           }
08537       }
08538     else
08539       {
08540         if(!list->def_data)
08541           err = -RSBAC_ENOTFOUND;
08542         else
08543           {
08544             if(ttl_p)
08545               *ttl_p = 0;
08546             if(data)
08547               memcpy(data,
08548                      list->def_data,
08549                      list->info.data_size);
08550           }
08551       }
08552     rsbac_read_unlock(&list->lock, &lock_flags);
08553     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08554     return err;
08555   }
08556 
08557 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08558 EXPORT_SYMBOL(rsbac_list_lol_get_data_ttl);
08559 #endif
08560 int rsbac_list_lol_get_data_ttl(rsbac_list_handle_t handle,
08561                                 rsbac_time_t * ttl_p,
08562                                 void * desc,
08563                                 void * data)
08564   {
08565     return rsbac_ta_list_lol_get_data_ttl(0, handle, ttl_p, desc, data);
08566   }
08567 
08568 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08569 EXPORT_SYMBOL(rsbac_list_lol_get_data);
08570 #endif
08571 int rsbac_list_lol_get_data(rsbac_list_handle_t handle,
08572                             void * desc,
08573                             void * data)
08574   {
08575     return rsbac_ta_list_lol_get_data_ttl(0, handle, NULL, desc, data);
08576   }
08577 
08578 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08579 EXPORT_SYMBOL(rsbac_ta_list_get_max_desc);
08580 #endif
08581 int rsbac_ta_list_get_max_desc(
08582   rsbac_list_ta_number_t ta_number,
08583   rsbac_list_handle_t handle,
08584   void * desc)
08585   {
08586     struct rsbac_list_reg_item_t * list;
08587     struct rsbac_list_item_t * item_p;
08588     u_long lock_flags, rlock_flags;
08589     int err = 0;
08590 
08591     if(!handle)
08592       return -RSBAC_EINVALIDVALUE;
08593     if(!list_initialized)
08594       return -RSBAC_ENOTINITIALIZED;
08595 
08596     list = (struct rsbac_list_reg_item_t *) handle;
08597     if(list->self != list)
08598       return -RSBAC_EINVALIDVALUE;
08599 
08600 #ifdef CONFIG_RSBAC_LIST_TRANS
08601     if(ta_number)
08602       {
08603         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08604           return -RSBAC_EINVALIDTRANSACTION;
08605       }
08606 #endif
08607 
08608     rsbac_read_lock(&reg_head.lock, &rlock_flags);
08609 /*
08610 #ifdef CONFIG_RSBAC_DEBUG
08611     if(rsbac_debug_lists)
08612       rsbac_printk(KERN_DEBUG "rsbac_list_get_max_desc: list %s.\n",
08613              list->name);
08614 #endif
08615 */
08616     rsbac_read_lock(&list->lock, &lock_flags);
08617 #ifdef CONFIG_RSBAC_LIST_TRANS
08618     if(ta_number && (list->ta_copied == ta_number))
08619       item_p = list->ta_tail;
08620     else
08621 #endif
08622     item_p = list->tail;
08623     while(   item_p
08624           && item_p->max_age
08625           && (item_p->max_age > RSBAC_CURRENT_TIME)
08626          )
08627       item_p = item_p->prev;
08628     if(item_p)
08629       memcpy(desc, (char *)item_p + sizeof(*item_p), list->info.desc_size);
08630     else
08631       {
08632         memset(desc, 0, list->info.desc_size);
08633         err = -RSBAC_ENOTFOUND;
08634       }
08635     rsbac_read_unlock(&list->lock, &lock_flags);
08636     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
08637     return err;
08638   }
08639 
08640 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08641 EXPORT_SYMBOL(rsbac_list_get_max_desc);
08642 #endif
08643 int rsbac_list_get_max_desc(rsbac_list_handle_t handle, void * desc)
08644   {
08645     return rsbac_ta_list_get_max_desc(0, handle, desc);
08646   }
08647 
08648 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08649 EXPORT_SYMBOL(rsbac_ta_list_get_next_desc);
08650 #endif
08651 int rsbac_ta_list_get_next_desc(
08652   rsbac_list_ta_number_t ta_number,
08653   rsbac_list_handle_t handle,
08654   void * old_desc,
08655   void * next_desc)
08656   {
08657     struct rsbac_list_reg_item_t * list;
08658     struct rsbac_list_item_t * item_p;
08659     u_long lock_flags, rlock_flags;
08660 
08661     if(!handle)
08662       return -RSBAC_EINVALIDVALUE;
08663     if(!list_initialized)
08664       return -RSBAC_ENOTINITIALIZED;
08665     if(!next_desc)
08666       return -RSBAC_EINVALIDPOINTER;
08667 
08668     list = (struct rsbac_list_reg_item_t *) handle;
08669     if(list->self != list)
08670       return -RSBAC_EINVALIDVALUE;
08671 
08672 #ifdef CONFIG_RSBAC_LIST_TRANS
08673     if(ta_number)
08674       {
08675         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08676           return -RSBAC_EINVALIDTRANSACTION;
08677       }
08678 #endif
08679 
08680     rsbac_read_lock(&reg_head.lock, &rlock_flags);
08681 /*
08682 #ifdef CONFIG_RSBAC_DEBUG
08683     if(rsbac_debug_lists)
08684       rsbac_printk(KERN_DEBUG "rsbac_list_get_next_desc: list %s.\n",
08685              list->name);
08686 #endif
08687 */
08688     rsbac_read_lock(&list->lock, &lock_flags);
08689     if(old_desc)
08690       {
08691 #ifdef CONFIG_RSBAC_LIST_TRANS
08692         if(ta_number && (list->ta_copied == ta_number))
08693           item_p = ta_lookup_item(ta_number, list, old_desc);
08694         else
08695 #endif
08696         item_p = lookup_item(list, old_desc);
08697         if(item_p)
08698           item_p = item_p->next;
08699       }
08700     else
08701 #ifdef CONFIG_RSBAC_LIST_TRANS
08702       if(ta_number && (list->ta_copied == ta_number))
08703         item_p = list->ta_head;
08704       else
08705 #endif
08706       item_p = list->head;
08707     while(   item_p
08708           && item_p->max_age
08709           && (item_p->max_age > RSBAC_CURRENT_TIME)
08710          )
08711       item_p = item_p->next;
08712     if(item_p)
08713       {
08714         memcpy(next_desc, (char *)item_p + sizeof(*item_p), list->info.desc_size);
08715         list->curr = item_p;
08716       }
08717     rsbac_read_unlock(&list->lock, &lock_flags);
08718     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
08719     if(item_p)
08720       return 0;
08721     else
08722       return -RSBAC_ENOTFOUND;
08723   }
08724 
08725 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08726 EXPORT_SYMBOL(rsbac_list_get_next_desc);
08727 #endif
08728 int rsbac_list_get_next_desc(rsbac_list_handle_t handle, void * old_desc, void * next_desc)
08729   {
08730     return rsbac_ta_list_get_next_desc(0, handle, old_desc, next_desc);
08731   }
08732 
08733 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08734 EXPORT_SYMBOL(rsbac_ta_list_lol_get_next_desc);
08735 #endif
08736 int rsbac_ta_list_lol_get_next_desc(
08737   rsbac_list_ta_number_t ta_number,
08738   rsbac_list_handle_t handle,
08739   void * old_desc,
08740   void * next_desc)
08741   {
08742     struct rsbac_list_lol_reg_item_t * list;
08743     struct rsbac_list_lol_item_t * item_p;
08744     u_long lock_flags, rlock_flags;
08745 
08746     if(!handle)
08747       return -RSBAC_EINVALIDVALUE;
08748     if(!list_initialized)
08749       return -RSBAC_ENOTINITIALIZED;
08750     if(!next_desc)
08751       return -RSBAC_EINVALIDPOINTER;
08752 
08753     list = (struct rsbac_list_lol_reg_item_t *) handle;
08754     if(list->self != list)
08755       return -RSBAC_EINVALIDVALUE;
08756 
08757 #ifdef CONFIG_RSBAC_LIST_TRANS
08758     if(ta_number)
08759       {
08760         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08761           return -RSBAC_EINVALIDTRANSACTION;
08762       }
08763 #endif
08764 
08765     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08766 /*
08767 #ifdef CONFIG_RSBAC_DEBUG
08768     if(rsbac_debug_lists)
08769       rsbac_printk(KERN_DEBUG "rsbac_list_lol_get_next_desc: list %s.\n",
08770              list->name);
08771 #endif
08772 */
08773     rsbac_read_lock(&list->lock, &lock_flags);
08774     if(old_desc)
08775       {
08776 #ifdef CONFIG_RSBAC_LIST_TRANS
08777         if(ta_number && (list->ta_copied == ta_number))
08778           item_p = ta_lookup_lol_item(ta_number, list, old_desc);
08779         else
08780 #endif
08781         item_p = lookup_lol_item(list, old_desc);
08782         if(item_p)
08783           item_p = item_p->next;
08784       }
08785     else
08786 #ifdef CONFIG_RSBAC_LIST_TRANS
08787       if(ta_number && (list->ta_copied == ta_number))
08788         item_p = list->ta_head;
08789       else
08790 #endif
08791       item_p = list->head;
08792     while(   item_p
08793           && item_p->max_age
08794           && (item_p->max_age > RSBAC_CURRENT_TIME)
08795          )
08796       item_p = item_p->next;
08797     if(item_p)
08798       {
08799         memcpy(next_desc, (char *)item_p + sizeof(*item_p), list->info.desc_size);
08800         list->curr = item_p;
08801       }
08802     rsbac_read_unlock(&list->lock, &lock_flags);
08803     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08804     if(item_p)
08805       return 0;
08806     else
08807       return -RSBAC_ENOTFOUND;
08808   }
08809 
08810 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08811 EXPORT_SYMBOL(rsbac_list_lol_get_next_desc);
08812 #endif
08813 int rsbac_list_lol_get_next_desc(
08814   rsbac_list_handle_t handle,
08815   void * old_desc,
08816   void * next_desc)
08817   {
08818     return rsbac_ta_list_lol_get_next_desc(0, handle, old_desc, next_desc);
08819   }
08820 
08821 /* get item desc by data */
08822 /* Item desc is copied - we cannot give a pointer, because item could be
08823  * removed.
08824  * If no compare function is provided (NULL value), memcmp is used.
08825  * Note: The data value given here is always used as second parameter to the
08826  *       compare function, so you can use different types for storage and
08827  *       lookup.
08828  */
08829 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08830 EXPORT_SYMBOL(rsbac_ta_list_get_desc);
08831 #endif
08832 int rsbac_ta_list_get_desc(
08833   rsbac_list_ta_number_t ta_number,
08834   rsbac_list_handle_t handle,
08835   void * desc,
08836   void * data,
08837   rsbac_list_data_compare_function_t compare)
08838   {
08839     struct rsbac_list_reg_item_t * list;
08840     struct rsbac_list_item_t     * item_p;
08841     u_long lock_flags, rlock_flags;
08842     int err = 0;
08843 
08844     if(!handle || !desc || !data)
08845       return -RSBAC_EINVALIDVALUE;
08846     if(!list_initialized)
08847       return -RSBAC_ENOTINITIALIZED;
08848 
08849     list = (struct rsbac_list_reg_item_t *) handle;
08850     if(list->self != list)
08851       return -RSBAC_EINVALIDVALUE;
08852 
08853 #ifdef CONFIG_RSBAC_LIST_TRANS
08854     if(ta_number)
08855       {
08856         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08857           return -RSBAC_EINVALIDTRANSACTION;
08858       }
08859 #endif
08860 
08861     rsbac_read_lock(&reg_head.lock, &rlock_flags);
08862 /*
08863 #ifdef CONFIG_RSBAC_DEBUG
08864     if(rsbac_debug_lists)
08865       rsbac_printk(KERN_DEBUG "rsbac_list_get_desc: getting desc from list %s.\n",
08866              list->name);
08867 #endif
08868 */
08869     if(!list->info.data_size)
08870       {
08871         rsbac_read_unlock(&reg_head.lock, &rlock_flags);
08872         return -RSBAC_EINVALIDREQUEST;
08873       }
08874 
08875     rsbac_read_lock(&list->lock, &lock_flags);
08876 
08877 #ifdef CONFIG_RSBAC_LIST_TRANS
08878     if(ta_number && (list->ta_copied == ta_number))
08879       item_p = ta_lookup_item_data(ta_number, list, data, compare);
08880     else
08881 #endif
08882     item_p = lookup_item_data(list, data, compare);
08883     if(item_p)
08884       { /* exists -> copy desc */
08885         memcpy(desc,
08886                ((char *) item_p) + sizeof(*item_p),
08887                list->info.desc_size);
08888       }
08889     else
08890       {
08891         err = -RSBAC_ENOTFOUND;
08892       }
08893     rsbac_read_unlock(&list->lock, &lock_flags);
08894     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
08895     return err;
08896   }
08897 
08898 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08899 EXPORT_SYMBOL(rsbac_list_get_desc);
08900 #endif
08901 int rsbac_list_get_desc(
08902   rsbac_list_handle_t handle,
08903   void * desc,
08904   void * data,
08905   rsbac_list_data_compare_function_t compare)
08906   {
08907     return rsbac_ta_list_get_desc(0, handle, desc, data, compare);
08908   }
08909 
08910 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08911 EXPORT_SYMBOL(rsbac_ta_list_lol_get_desc);
08912 #endif
08913 int rsbac_ta_list_lol_get_desc(
08914   rsbac_list_ta_number_t ta_number,
08915   rsbac_list_handle_t handle,
08916   void * desc,
08917   void * data,
08918   rsbac_list_data_compare_function_t compare)
08919   {
08920     struct rsbac_list_lol_reg_item_t * list;
08921     struct rsbac_list_lol_item_t     * item_p;
08922     u_long lock_flags, rlock_flags;
08923     int err = 0;
08924 
08925     if(!handle || !desc || !data)
08926       return -RSBAC_EINVALIDVALUE;
08927     if(!list_initialized)
08928       return -RSBAC_ENOTINITIALIZED;
08929 
08930     list = (struct rsbac_list_lol_reg_item_t *) handle;
08931     if(list->self != list)
08932       return -RSBAC_EINVALIDVALUE;
08933 
08934 #ifdef CONFIG_RSBAC_LIST_TRANS
08935     if(ta_number)
08936       {
08937         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08938           return -RSBAC_EINVALIDTRANSACTION;
08939       }
08940 #endif
08941 
08942     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08943 /*
08944 #ifdef CONFIG_RSBAC_DEBUG
08945     if(rsbac_debug_lists)
08946       rsbac_printk(KERN_DEBUG "rsbac_list_lol_get_desc: getting desc from list %s.\n",
08947              list->name);
08948 #endif
08949 */
08950     if(!list->info.data_size)
08951       {
08952         rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08953         return -RSBAC_EINVALIDREQUEST;
08954       }
08955 
08956     rsbac_read_lock(&list->lock, &lock_flags);
08957 
08958 #ifdef CONFIG_RSBAC_LIST_TRANS
08959     if(ta_number && (list->ta_copied == ta_number))
08960       item_p = ta_lookup_lol_item_data(ta_number, list, data, compare);
08961     else
08962 #endif
08963     item_p = lookup_lol_item_data(list, data, compare);
08964     if(item_p)
08965       { /* exists -> copy desc */
08966         memcpy(desc,
08967                ((char *) item_p) + sizeof(*item_p),
08968                list->info.desc_size);
08969       }
08970     else
08971       {
08972         err = -RSBAC_ENOTFOUND;
08973       }
08974     rsbac_read_unlock(&list->lock, &lock_flags);
08975     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08976     return err;
08977   }
08978 
08979 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08980 EXPORT_SYMBOL(rsbac_list_lol_get_desc);
08981 #endif
08982 int rsbac_list_lol_get_desc(
08983   rsbac_list_handle_t handle,
08984   void * desc,
08985   void * data,
08986   rsbac_list_data_compare_function_t compare)
08987   {
08988     return rsbac_ta_list_lol_get_desc(0, handle, desc, data, compare);
08989   }
08990 
08991 /* returns TRUE, if item exists or def_data is defined, FALSE, if not */
08992 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08993 EXPORT_SYMBOL(rsbac_ta_list_exist);
08994 #endif
08995 int rsbac_ta_list_exist(
08996   rsbac_list_ta_number_t ta_number,
08997   rsbac_list_handle_t handle,
08998   void * desc)
08999   {
09000     struct rsbac_list_reg_item_t * list;
09001     u_long lock_flags, rlock_flags;
09002     struct rsbac_list_item_t     * item_p;
09003     int result;
09004 
09005     if(!handle || !desc)
09006       return FALSE;
09007     if(!list_initialized)
09008       return FALSE;
09009 
09010     list = (struct rsbac_list_reg_item_t *) handle;
09011     if(list->self != list)
09012       return -RSBAC_EINVALIDVALUE;
09013 
09014 #ifdef CONFIG_RSBAC_LIST_TRANS
09015     if(ta_number)
09016       {
09017         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09018           return -RSBAC_EINVALIDTRANSACTION;
09019       }
09020 #endif
09021 
09022     rsbac_read_lock(&reg_head.lock, &rlock_flags);
09023 /*
09024 #ifdef CONFIG_RSBAC_DEBUG
09025     if(rsbac_debug_lists)
09026       rsbac_printk(KERN_DEBUG "rsbac_list_exist: testing on list %s.\n",
09027              list->name);
09028 #endif
09029 */
09030     rsbac_read_lock(&list->lock, &lock_flags);
09031 
09032 #ifdef CONFIG_RSBAC_LIST_TRANS
09033     if(ta_number && (list->ta_copied == ta_number))
09034       item_p = ta_lookup_item(ta_number, list, desc);
09035     else
09036 #endif
09037     item_p = lookup_item(list, desc);
09038     if(   item_p
09039        && (   !item_p->max_age
09040            || (item_p->max_age > RSBAC_CURRENT_TIME)
09041           )
09042       )
09043       { /* exists -> TRUE */
09044         result = TRUE;
09045       }
09046     else
09047       {
09048         result = FALSE;
09049       }
09050     rsbac_read_unlock(&list->lock, &lock_flags);
09051     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
09052     return result;
09053   }
09054 
09055 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09056 EXPORT_SYMBOL(rsbac_list_exist);
09057 #endif
09058 int rsbac_list_exist(
09059   rsbac_list_handle_t handle,
09060   void * desc)
09061   {
09062     return rsbac_ta_list_exist(0, handle, desc);
09063   }
09064 
09065 /* does item exist? */
09066 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09067 EXPORT_SYMBOL(rsbac_ta_list_lol_subexist);
09068 #endif
09069 int rsbac_ta_list_lol_subexist(
09070   rsbac_list_ta_number_t ta_number,
09071   rsbac_list_handle_t handle,
09072   void * desc,
09073   void * subdesc)
09074   {
09075     struct rsbac_list_lol_reg_item_t * list;
09076     struct rsbac_list_lol_item_t     * sublist;
09077     u_long lock_flags, rlock_flags;
09078     struct rsbac_list_item_t     * item_p;
09079     int result;
09080 
09081     if(!handle || !desc || !subdesc)
09082       return FALSE;
09083     if(!list_initialized)
09084       return FALSE;
09085 
09086     list = (struct rsbac_list_lol_reg_item_t *) handle;
09087     if(list->self != list)
09088       return -RSBAC_EINVALIDVALUE;
09089 
09090 #ifdef CONFIG_RSBAC_LIST_TRANS
09091     if(ta_number)
09092       {
09093         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09094           return -RSBAC_EINVALIDTRANSACTION;
09095       }
09096 #endif
09097 
09098     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09099 /*
09100 #ifdef CONFIG_RSBAC_DEBUG
09101     if(rsbac_debug_lists)
09102       rsbac_printk(KERN_DEBUG "rsbac_list_lol_subexist: testing on list %s.\n",
09103              list->name);
09104 #endif
09105 */
09106     rsbac_read_lock(&list->lock, &lock_flags);
09107 
09108 #ifdef CONFIG_RSBAC_LIST_TRANS
09109     if(ta_number && (list->ta_copied == ta_number))
09110       sublist = ta_lookup_lol_item(ta_number, list, desc);
09111     else
09112 #endif
09113     sublist = lookup_lol_item(list, desc);
09114     if(sublist)
09115       { /* exists -> lookup subitem */
09116         item_p = lookup_lol_subitem(list, sublist, subdesc);
09117         if(   item_p
09118            && (   !item_p->max_age
09119                || (item_p->max_age > RSBAC_CURRENT_TIME)
09120               )
09121           )
09122           { /* exists -> TRUE */
09123             result = TRUE;
09124           }
09125         else
09126           {
09127             result = FALSE;
09128           }
09129       }
09130     else
09131       {
09132         result = FALSE;
09133       }
09134     rsbac_read_unlock(&list->lock, &lock_flags);
09135     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09136     return result;
09137   }
09138 
09139 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09140 EXPORT_SYMBOL(rsbac_list_lol_subexist);
09141 #endif
09142 int rsbac_list_lol_subexist(
09143   rsbac_list_handle_t handle,
09144   void * desc,
09145   void * subdesc)
09146   {
09147     return rsbac_ta_list_lol_subexist(0, handle, desc, subdesc);
09148   }
09149 
09150 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09151 EXPORT_SYMBOL(rsbac_ta_list_lol_subexist_compare);
09152 #endif
09153 int rsbac_ta_list_lol_subexist_compare(
09154   rsbac_list_ta_number_t ta_number,
09155   rsbac_list_handle_t handle,
09156   void * desc,
09157   void * subdesc,
09158   rsbac_list_compare_function_t compare)
09159   {
09160     struct rsbac_list_lol_reg_item_t * list;
09161     struct rsbac_list_lol_item_t     * sublist;
09162     u_long lock_flags, rlock_flags;
09163     struct rsbac_list_item_t     * item_p;
09164     int result;
09165 
09166     if(!handle || !desc || !subdesc)
09167       return FALSE;
09168     if(!list_initialized)
09169       return FALSE;
09170     /* Use standard function, if compare is not provided. */
09171     if(!compare)
09172       return rsbac_list_lol_subexist(handle, desc, subdesc);
09173 
09174     list = (struct rsbac_list_lol_reg_item_t *) handle;
09175     if(list->self != list)
09176       return -RSBAC_EINVALIDVALUE;
09177 
09178 #ifdef CONFIG_RSBAC_LIST_TRANS
09179     if(ta_number)
09180       {
09181         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09182           return -RSBAC_EINVALIDTRANSACTION;
09183       }
09184 #endif
09185 
09186     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09187 /*
09188 #ifdef CONFIG_RSBAC_DEBUG
09189     if(rsbac_debug_lists)
09190       rsbac_printk(KERN_DEBUG "rsbac_list_lol_subexist_compare: testing on list %s.\n",
09191              list->name);
09192 #endif
09193 */
09194     rsbac_read_lock(&list->lock, &lock_flags);
09195 
09196 #ifdef CONFIG_RSBAC_LIST_TRANS
09197     if(ta_number && (list->ta_copied == ta_number))
09198       sublist = ta_lookup_lol_item(ta_number, list, desc);
09199     else
09200 #endif
09201     sublist = lookup_lol_item(list, desc);
09202     if(sublist)
09203       { /* exists -> lookup subitem */
09204         item_p = lookup_lol_subitem_user_compare(list, sublist, subdesc, compare);
09205         if(   item_p
09206            && (   !item_p->max_age
09207                || (item_p->max_age > RSBAC_CURRENT_TIME)
09208               )
09209           )
09210           { /* exists -> TRUE */
09211             result = TRUE;
09212           }
09213         else
09214           {
09215             result = FALSE;
09216           }
09217       }
09218     else
09219       {
09220         result = FALSE;
09221       }
09222     rsbac_read_unlock(&list->lock, &lock_flags);
09223     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09224     return result;
09225   }
09226 
09227 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09228 EXPORT_SYMBOL(rsbac_list_lol_subexist_compare);
09229 #endif
09230 int rsbac_list_lol_subexist_compare(
09231   rsbac_list_handle_t handle,
09232   void * desc,
09233   void * subdesc,
09234   rsbac_list_compare_function_t compare)
09235   {
09236     return rsbac_ta_list_lol_subexist_compare(0, handle,
09237                                               desc, subdesc, compare);
09238   }
09239 
09240 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09241 EXPORT_SYMBOL(rsbac_ta_list_lol_exist);
09242 #endif
09243 int rsbac_ta_list_lol_exist(
09244   rsbac_list_ta_number_t ta_number,
09245   rsbac_list_handle_t handle,
09246   void * desc)
09247   {
09248     struct rsbac_list_lol_reg_item_t * list;
09249     u_long lock_flags, rlock_flags;
09250     struct rsbac_list_lol_item_t     * item_p;
09251     int result;
09252 
09253     if(!handle || !desc)
09254       return FALSE;
09255     if(!list_initialized)
09256       return FALSE;
09257 
09258     list = (struct rsbac_list_lol_reg_item_t *) handle;
09259     if(list->self != list)
09260       return -RSBAC_EINVALIDVALUE;
09261 
09262 #ifdef CONFIG_RSBAC_LIST_TRANS
09263     if(ta_number)
09264       {
09265         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09266           return -RSBAC_EINVALIDTRANSACTION;
09267       }
09268 #endif
09269 
09270     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09271 /*
09272 #ifdef CONFIG_RSBAC_DEBUG
09273     if(rsbac_debug_lists)
09274       rsbac_printk(KERN_DEBUG "rsbac_list_lol_exist: testing on list %s.\n",
09275              list->name);
09276 #endif
09277 */
09278     rsbac_read_lock(&list->lock, &lock_flags);
09279 
09280 #ifdef CONFIG_RSBAC_LIST_TRANS
09281     if(ta_number && (list->ta_copied == ta_number))
09282       item_p = ta_lookup_lol_item(ta_number, list, desc);
09283     else
09284 #endif
09285     item_p = lookup_lol_item(list, desc);
09286     if(   item_p
09287        && (   !item_p->max_age
09288            || (item_p->max_age > RSBAC_CURRENT_TIME)
09289           )
09290       )
09291       { /* exists -> TRUE */
09292         result = TRUE;
09293       }
09294     else
09295       {
09296         result = FALSE;
09297       }
09298     rsbac_read_unlock(&list->lock, &lock_flags);
09299     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09300     return result;
09301   }
09302 
09303 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09304 EXPORT_SYMBOL(rsbac_list_lol_exist);
09305 #endif
09306 int rsbac_list_lol_exist(
09307   rsbac_list_handle_t handle,
09308   void * desc)
09309   {
09310     return rsbac_ta_list_lol_exist(0, handle, desc);
09311   }
09312 
09313 /* count number of elements */
09314 /* returns number of elements or negative error code */
09315 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09316 EXPORT_SYMBOL(rsbac_ta_list_lol_subcount);
09317 #endif
09318 long rsbac_ta_list_lol_subcount(
09319   rsbac_list_ta_number_t ta_number,
09320   rsbac_list_handle_t handle,
09321   void * desc)
09322   {
09323     struct rsbac_list_lol_reg_item_t * list;
09324     struct rsbac_list_lol_item_t     * sublist;
09325     u_long lock_flags, rlock_flags;
09326     long result;
09327 
09328     if(!handle)
09329       return -RSBAC_EINVALIDVALUE;
09330     if(!list_initialized)
09331       return -RSBAC_ENOTINITIALIZED;
09332 
09333     list = (struct rsbac_list_lol_reg_item_t *) handle;
09334     if(list->self != list)
09335       return -RSBAC_EINVALIDVALUE;
09336 
09337 #ifdef CONFIG_RSBAC_LIST_TRANS
09338     if(ta_number)
09339       {
09340         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09341           return -RSBAC_EINVALIDTRANSACTION;
09342       }
09343 #endif
09344 
09345     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09346 /*
09347 #ifdef CONFIG_RSBAC_DEBUG
09348     if(rsbac_debug_lists)
09349       rsbac_printk(KERN_DEBUG "rsbac_list_lol_subcount: list %s.\n",
09350              list->name);
09351 #endif
09352 */
09353     rsbac_read_lock(&list->lock, &lock_flags);
09354 
09355 #ifdef CONFIG_RSBAC_LIST_TRANS
09356     if(ta_number && (list->ta_copied == ta_number))
09357       sublist = ta_lookup_lol_item(ta_number, list, desc);
09358     else
09359 #endif
09360     sublist = lookup_lol_item(list, desc);
09361     if(sublist)
09362       {
09363         result = sublist->count;
09364       }
09365     else
09366       {
09367         result = -RSBAC_ENOTFOUND;
09368       }
09369     rsbac_read_unlock(&list->lock, &lock_flags);
09370     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09371     return result;
09372   }
09373 
09374 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09375 EXPORT_SYMBOL(rsbac_list_lol_subcount);
09376 #endif
09377 long rsbac_list_lol_subcount(
09378   rsbac_list_handle_t handle,
09379   void * desc)
09380   {
09381     return rsbac_ta_list_lol_subcount(0, handle, desc);
09382   }
09383 
09384 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09385 EXPORT_SYMBOL(rsbac_ta_list_lol_all_subcount);
09386 #endif
09387 long rsbac_ta_list_lol_all_subcount(
09388   rsbac_list_ta_number_t ta_number,
09389   rsbac_list_handle_t handle)
09390   {
09391     struct rsbac_list_lol_reg_item_t * list;
09392     struct rsbac_list_lol_item_t     * sublist;
09393     u_long lock_flags, rlock_flags;
09394     long result = 0;
09395 
09396     if(!handle)
09397       return -RSBAC_EINVALIDVALUE;
09398     if(!list_initialized)
09399       return -RSBAC_ENOTINITIALIZED;
09400 
09401     list = (struct rsbac_list_lol_reg_item_t *) handle;
09402     if(list->self != list)
09403       return -RSBAC_EINVALIDVALUE;
09404 
09405 #ifdef CONFIG_RSBAC_LIST_TRANS
09406     if(ta_number)
09407       {
09408         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09409           return -RSBAC_EINVALIDTRANSACTION;
09410       }
09411 #endif
09412 
09413     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09414 /*
09415 #ifdef CONFIG_RSBAC_DEBUG
09416     if(rsbac_debug_lists)
09417       rsbac_printk(KERN_DEBUG "rsbac_list_lol_subcount: list %s.\n",
09418              list->name);
09419 #endif
09420 */
09421     rsbac_read_lock(&list->lock, &lock_flags);
09422 
09423 #ifdef CONFIG_RSBAC_LIST_TRANS
09424     if(ta_number && (list->ta_copied == ta_number))
09425       sublist = list->ta_head;
09426     else
09427 #endif
09428     sublist = list->head;
09429     while(sublist)
09430       {
09431         result += sublist->count;
09432         sublist = sublist->next;
09433       }
09434     rsbac_read_unlock(&list->lock, &lock_flags);
09435     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09436     return result;
09437   }
09438 
09439 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09440 EXPORT_SYMBOL(rsbac_list_lol_all_subcount);
09441 #endif
09442 long rsbac_list_lol_all_subcount(rsbac_list_handle_t handle)
09443   {
09444     return rsbac_ta_list_lol_all_subcount(0, handle);
09445   }
09446 
09447 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09448 EXPORT_SYMBOL(rsbac_ta_list_lol_count);
09449 #endif
09450 long rsbac_ta_list_lol_count(
09451   rsbac_list_ta_number_t ta_number,
09452   rsbac_list_handle_t handle)
09453   {
09454     struct rsbac_list_lol_reg_item_t * list;
09455 
09456     if(!handle)
09457       return -RSBAC_EINVALIDVALUE;
09458     if(!list_initialized)
09459       return -RSBAC_ENOTINITIALIZED;
09460 
09461     list = (struct rsbac_list_lol_reg_item_t *) handle;
09462     if(list->self != list)
09463       return -RSBAC_EINVALIDVALUE;
09464 
09465 #ifdef CONFIG_RSBAC_LIST_TRANS
09466     if(ta_number)
09467       {
09468         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09469           return -RSBAC_EINVALIDTRANSACTION;
09470       }
09471 #endif
09472 
09473 /*
09474 #ifdef CONFIG_RSBAC_DEBUG
09475     if(rsbac_debug_lists)
09476       rsbac_printk(KERN_DEBUG "rsbac_list_lol_count: list %s.\n",
09477              list->name);
09478 #endif
09479 */
09480 #ifdef CONFIG_RSBAC_LIST_TRANS
09481     if(ta_number && (list->ta_copied == ta_number))
09482       return list->ta_count;
09483     else
09484 #endif
09485     return list->count;
09486   }
09487 
09488 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09489 EXPORT_SYMBOL(rsbac_list_lol_count);
09490 #endif
09491 long rsbac_list_lol_count(rsbac_list_handle_t handle)
09492   {
09493     return rsbac_ta_list_lol_count(0, handle);
09494   }
09495 
09496 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09497 EXPORT_SYMBOL(rsbac_ta_list_count);
09498 #endif
09499 long rsbac_ta_list_count(
09500   rsbac_list_ta_number_t ta_number,
09501   rsbac_list_handle_t handle)
09502   {
09503     struct rsbac_list_reg_item_t * list;
09504 
09505     if(!handle)
09506       return -RSBAC_EINVALIDVALUE;
09507     if(!list_initialized)
09508       return -RSBAC_ENOTINITIALIZED;
09509 
09510     list = (struct rsbac_list_reg_item_t *) handle;
09511     if(list->self != list)
09512       return -RSBAC_EINVALIDVALUE;
09513 
09514 #ifdef CONFIG_RSBAC_LIST_TRANS
09515     if(ta_number)
09516       {
09517         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09518           return -RSBAC_EINVALIDTRANSACTION;
09519       }
09520 #endif
09521 
09522 #ifdef CONFIG_RSBAC_LIST_TRANS
09523     if(ta_number && (list->ta_copied == ta_number))
09524       return list->ta_count;
09525     else
09526 #endif
09527     return list->count;
09528   }
09529 
09530 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09531 EXPORT_SYMBOL(rsbac_list_count);
09532 #endif
09533 long rsbac_list_count(rsbac_list_handle_t handle)
09534   {
09535     return rsbac_ta_list_count(0, handle);
09536   }
09537 
09538 /* Get array of all descriptors */
09539 /* Returns number of elements or negative error code */
09540 /* If return value > 0, *array_p contains a pointer to a vmalloc'd array of descs,
09541    otherwise *array_p is set to NULL. If *array_p has been set, caller must call
09542    rsbac_vfree(*array_p) after use! */
09543 
09544 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09545 EXPORT_SYMBOL(rsbac_ta_list_get_all_desc);
09546 #endif
09547 long rsbac_ta_list_get_all_desc(
09548   rsbac_list_ta_number_t ta_number,
09549   rsbac_list_handle_t handle,
09550   void ** array_p)
09551   {
09552     struct rsbac_list_reg_item_t * list;
09553     struct rsbac_list_item_t     * item_p;
09554            char                  * buffer;
09555     u_long lock_flags, rlock_flags;
09556     u_long offset = 0;
09557     long result = 0;
09558     u_int item_size;
09559 
09560     if(!handle)
09561       return -RSBAC_EINVALIDVALUE;
09562     if(!array_p)
09563       return -RSBAC_EINVALIDVALUE;
09564     if(!list_initialized)
09565       return -RSBAC_ENOTINITIALIZED;
09566 
09567     list = (struct rsbac_list_reg_item_t *) handle;
09568     if(list->self != list)
09569       return -RSBAC_EINVALIDVALUE;
09570     *array_p = NULL;
09571 
09572 #ifdef CONFIG_RSBAC_LIST_TRANS
09573     if(ta_number)
09574       {
09575         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09576           return -RSBAC_EINVALIDTRANSACTION;
09577       }
09578 #endif
09579 
09580     rsbac_read_lock(&reg_head.lock, &rlock_flags);
09581 /*
09582 #ifdef CONFIG_RSBAC_DEBUG
09583     if(rsbac_debug_lists)
09584       rsbac_printk(KERN_DEBUG "rsbac_list_get_all_desc: list %s.\n",
09585              list->name);
09586 #endif
09587 */
09588     rsbac_read_lock(&list->lock, &lock_flags);
09589 #ifdef CONFIG_RSBAC_LIST_TRANS
09590     if(ta_number && (list->ta_copied == ta_number))
09591       {
09592         if(list->ta_count)
09593           {
09594             item_size = list->info.desc_size;
09595             buffer = rsbac_vmalloc(item_size * list->ta_count);
09596             if(buffer)
09597               {
09598                 item_p = list->ta_head;
09599                 while(item_p)
09600                   {
09601                     if(   !item_p->max_age
09602                        || (item_p->max_age > RSBAC_CURRENT_TIME)
09603                       )
09604                       {
09605                         memcpy(buffer + offset,
09606                                ((char *) item_p) + sizeof(*item_p),
09607                                item_size);
09608                         offset += item_size;
09609                         result++;
09610                       }
09611                     item_p = item_p->next;
09612                   }
09613                 *array_p = buffer;
09614               }
09615             else
09616               {
09617                 result = -RSBAC_ENOMEM;
09618               }
09619           }
09620       }
09621     else
09622 #endif
09623     if(list->count)
09624       {
09625         item_size = list->info.desc_size;
09626         buffer = rsbac_vmalloc(item_size * list->count);
09627         if(buffer)
09628           {
09629             item_p = list->head;
09630             while(item_p)
09631               {
09632                 if(   !item_p->max_age
09633                    || (item_p->max_age > RSBAC_CURRENT_TIME)
09634                   )
09635                   {
09636                     memcpy(buffer + offset,
09637                            ((char *) item_p) + sizeof(*item_p),
09638                            item_size);
09639                     offset += item_size;
09640                     result++;
09641                   }
09642                 item_p = item_p->next;
09643               }
09644             *array_p = buffer;
09645           }
09646         else
09647           {
09648             result = -RSBAC_ENOMEM;
09649           }
09650       }
09651     rsbac_read_unlock(&list->lock, &lock_flags);
09652     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
09653     return result;
09654   }
09655 
09656 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09657 EXPORT_SYMBOL(rsbac_list_get_all_desc);
09658 #endif
09659 long rsbac_list_get_all_desc(
09660   rsbac_list_handle_t handle,
09661   void ** array_p)
09662   {
09663     return rsbac_ta_list_get_all_desc(0, handle, array_p);
09664   }
09665 
09666 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09667 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_subdesc_ttl);
09668 #endif
09669 long rsbac_ta_list_lol_get_all_subdesc_ttl(
09670   rsbac_list_ta_number_t ta_number,
09671   rsbac_list_handle_t handle,
09672   void * desc,
09673   void ** array_p,
09674   rsbac_time_t ** ttl_array_p)
09675   {
09676     struct rsbac_list_lol_reg_item_t * list;
09677     struct rsbac_list_lol_item_t     * sublist;
09678     struct rsbac_list_item_t         * item_p;
09679            char                      * buffer;
09680            rsbac_time_t              * ttl_p = NULL;
09681     u_long lock_flags, rlock_flags;
09682     u_long offset = 0;
09683     long result = 0;
09684     u_int item_size;
09685 
09686     if(!handle)
09687       return -RSBAC_EINVALIDVALUE;
09688     if(!array_p)
09689       return -RSBAC_EINVALIDVALUE;
09690     if(!list_initialized)
09691       return -RSBAC_ENOTINITIALIZED;
09692 
09693     list = (struct rsbac_list_lol_reg_item_t *) handle;
09694     if(list->self != list)
09695       return -RSBAC_EINVALIDVALUE;
09696     *array_p = NULL;
09697 
09698 #ifdef CONFIG_RSBAC_LIST_TRANS
09699     if(ta_number)
09700       {
09701         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09702           return -RSBAC_EINVALIDTRANSACTION;
09703       }
09704 #endif
09705 
09706     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09707 /*
09708 #ifdef CONFIG_RSBAC_DEBUG
09709     if(rsbac_debug_lists)
09710       rsbac_printk(KERN_DEBUG "rsbac_list_lol_get_all_desc: list %s.\n",
09711              list->name);
09712 #endif
09713 */
09714     rsbac_read_lock(&list->lock, &lock_flags);
09715 #ifdef CONFIG_RSBAC_LIST_TRANS
09716     if(ta_number && (list->ta_copied == ta_number))
09717       sublist = ta_lookup_lol_item(ta_number, list, desc);
09718     else
09719 #endif
09720     sublist = lookup_lol_item(list, desc);
09721     if(sublist && sublist->count)
09722       {
09723         item_size = list->info.subdesc_size;
09724         buffer = rsbac_vmalloc(item_size * sublist->count);
09725         if(buffer)
09726           {
09727             if(ttl_array_p)
09728               ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * sublist->count);
09729             item_p = sublist->head;
09730             while(item_p)
09731               {
09732                 if(   !item_p->max_age
09733                    || (item_p->max_age > RSBAC_CURRENT_TIME)
09734                   )
09735                   {
09736                     memcpy(buffer + offset,
09737                            ((char *) item_p) + sizeof(*item_p),
09738                            item_size);
09739                     if(ttl_p)
09740                       {
09741                         if(item_p->max_age)
09742                           ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME;
09743                         else
09744                           ttl_p[result] = 0;
09745                       }
09746                     offset += item_size;
09747                     result++;
09748                   }
09749                 item_p = item_p->next;
09750               }
09751             *array_p = buffer;
09752             if(ttl_array_p)
09753               *ttl_array_p = ttl_p;
09754           }
09755         else
09756           {
09757             result = -RSBAC_ENOMEM;
09758           }
09759       }
09760     rsbac_read_unlock(&list->lock, &lock_flags);
09761     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09762     return result;
09763   }
09764 
09765 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09766 EXPORT_SYMBOL(rsbac_list_lol_get_all_subdesc_ttl);
09767 #endif
09768 long rsbac_list_lol_get_all_subdesc_ttl(
09769   rsbac_list_handle_t handle,
09770   void * desc,
09771   void ** array_p,
09772   rsbac_time_t ** ttl_array_p)
09773   {
09774     return rsbac_ta_list_lol_get_all_subdesc_ttl(0,
09775                                                  handle,
09776                                                  desc,
09777                                                  array_p,
09778                                                  ttl_array_p);
09779   }
09780 
09781 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09782 EXPORT_SYMBOL(rsbac_list_lol_get_all_subdesc);
09783 #endif
09784 long rsbac_list_lol_get_all_subdesc(rsbac_list_handle_t handle, void * desc, void ** array_p)
09785   {
09786     return rsbac_ta_list_lol_get_all_subdesc_ttl(0, handle,
09787                                                  desc, array_p, NULL);
09788   }
09789 
09790 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09791 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_desc);
09792 #endif
09793 long rsbac_ta_list_lol_get_all_desc(
09794   rsbac_list_ta_number_t ta_number,
09795   rsbac_list_handle_t handle,
09796   void ** array_p)
09797   {
09798     struct rsbac_list_lol_reg_item_t * list;
09799     struct rsbac_list_lol_item_t     * item_p;
09800            char                      * buffer;
09801     u_long lock_flags, rlock_flags;
09802     u_long offset = 0;
09803     long result = 0;
09804     u_int item_size;
09805 
09806     if(!handle)
09807       return -RSBAC_EINVALIDVALUE;
09808     if(!array_p)
09809       return -RSBAC_EINVALIDVALUE;
09810     if(!list_initialized)
09811       return -RSBAC_ENOTINITIALIZED;
09812 
09813     list = (struct rsbac_list_lol_reg_item_t *) handle;
09814     if(list->self != list)
09815       return -RSBAC_EINVALIDVALUE;
09816     *array_p = NULL;
09817 
09818 #ifdef CONFIG_RSBAC_LIST_TRANS
09819     if(ta_number)
09820       {
09821         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09822           return -RSBAC_EINVALIDTRANSACTION;
09823       }
09824 #endif
09825 
09826     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09827 /*
09828 #ifdef CONFIG_RSBAC_DEBUG
09829     if(rsbac_debug_lists)
09830       rsbac_printk(KERN_DEBUG "rsbac_list_lol_get_all_desc: list %s.\n",
09831              list->name);
09832 #endif
09833 */
09834     rsbac_read_lock(&list->lock, &lock_flags);
09835 #ifdef CONFIG_RSBAC_LIST_TRANS
09836     if(ta_number && (list->ta_copied == ta_number))
09837       {
09838         if(list->ta_count)
09839           {
09840             item_size = list->info.desc_size;
09841             buffer = rsbac_vmalloc(item_size * list->ta_count);
09842             if(buffer)
09843               {
09844                 item_p = list->ta_head;
09845                 while(item_p)
09846                   {
09847                     if(   !item_p->max_age
09848                        || (item_p->max_age > RSBAC_CURRENT_TIME)
09849                       )
09850                       {
09851                         memcpy(buffer + offset,
09852                                ((char *) item_p) + sizeof(*item_p),
09853                                item_size);
09854                         offset += item_size;
09855                         result++;
09856                       }
09857                     item_p = item_p->next;
09858                   }
09859                 *array_p = buffer;
09860               }
09861             else
09862               {
09863                 result = -RSBAC_ENOMEM;
09864               }
09865           }
09866       }
09867     else
09868 #endif
09869     if(list->count)
09870       {
09871         item_size = list->info.desc_size;
09872         buffer = rsbac_vmalloc(item_size * list->count);
09873         if(buffer)
09874           {
09875             item_p = list->head;
09876             while(item_p)
09877               {
09878                 if(   !item_p->max_age
09879                    || (item_p->max_age > RSBAC_CURRENT_TIME)
09880                   )
09881                   {
09882                     memcpy(buffer + offset,
09883                            ((char *) item_p) + sizeof(*item_p),
09884                            item_size);
09885                     offset += item_size;
09886                     result++;
09887                   }
09888                 item_p = item_p->next;
09889               }
09890             *array_p = buffer;
09891           }
09892         else
09893           {
09894             result = -RSBAC_ENOMEM;
09895           }
09896       }
09897     rsbac_read_unlock(&list->lock, &lock_flags);
09898     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09899     return result;
09900   }
09901 
09902 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09903 EXPORT_SYMBOL(rsbac_list_lol_get_all_desc);
09904 #endif
09905 long rsbac_list_lol_get_all_desc(rsbac_list_handle_t handle, void ** array_p)
09906   {
09907     return rsbac_ta_list_lol_get_all_desc(0, handle, array_p);
09908   }
09909 
09910 /* Get array of all data */
09911 /* Returns number of elements or negative error code */
09912 /* If return value > 0, *array_p contains a pointer to a vmalloc'd array of datas,
09913    otherwise *array_p is set to NULL. If *array_p has been set, caller must call
09914    rsbac_vfree(*array_p) after use! */
09915 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09916 EXPORT_SYMBOL(rsbac_ta_list_get_all_data);
09917 #endif
09918 long rsbac_ta_list_get_all_data(
09919   rsbac_list_ta_number_t ta_number,
09920   rsbac_list_handle_t handle,
09921   void ** array_p)
09922   {
09923     struct rsbac_list_reg_item_t * list;
09924     struct rsbac_list_item_t     * item_p;
09925            char                  * buffer;
09926     u_long lock_flags, rlock_flags;
09927     u_long offset = 0;
09928     long result = 0;
09929     u_int item_size;
09930     u_int item_offset;
09931 
09932     if(!handle)
09933       return -RSBAC_EINVALIDVALUE;
09934     if(!array_p)
09935       return -RSBAC_EINVALIDVALUE;
09936     if(!list_initialized)
09937       return -RSBAC_ENOTINITIALIZED;
09938 
09939     list = (struct rsbac_list_reg_item_t *) handle;
09940     if(list->self != list)
09941       return -RSBAC_EINVALIDVALUE;
09942     *array_p = NULL;
09943 
09944 #ifdef CONFIG_RSBAC_LIST_TRANS
09945     if(ta_number)
09946       {
09947         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09948           return -RSBAC_EINVALIDTRANSACTION;
09949       }
09950 #endif
09951 
09952     rsbac_read_lock(&reg_head.lock, &rlock_flags);
09953 /*
09954 #ifdef CONFIG_RSBAC_DEBUG
09955     if(rsbac_debug_lists)
09956       rsbac_printk(KERN_DEBUG "rsbac_list_get_all_data: list %s.\n",
09957              list->name);
09958 #endif
09959 */
09960     rsbac_read_lock(&list->lock, &lock_flags);
09961     if(!list->info.data_size)
09962       {
09963         rsbac_read_unlock(&list->lock, &lock_flags);
09964         rsbac_read_unlock(&reg_head.lock, &rlock_flags);
09965         return -RSBAC_EINVALIDREQUEST;
09966       }
09967 #ifdef CONFIG_RSBAC_LIST_TRANS
09968     if(ta_number && (list->ta_copied == ta_number))
09969       {
09970         if(list->ta_count)
09971           {
09972             item_size = list->info.data_size;
09973             item_offset = list->info.desc_size;
09974             buffer = rsbac_vmalloc(item_size * list->ta_count);
09975             if(buffer)
09976               {
09977                 item_p = list->ta_head;
09978                 while(item_p)
09979                   {
09980                     if(   !item_p->max_age
09981                        || (item_p->max_age > RSBAC_CURRENT_TIME)
09982                       )
09983                       {
09984                         memcpy(buffer + offset,
09985                                ((char *) item_p) + sizeof(*item_p) + item_offset,
09986                                item_size);
09987                         offset += item_size;
09988                         result++;
09989                       }
09990                     item_p = item_p->next;
09991                   }
09992                 *array_p = buffer;
09993               }
09994             else
09995               {
09996                 result = -RSBAC_ENOMEM;
09997               }
09998           }
09999       }
10000     else
10001 #endif
10002     if(list->count)
10003       {
10004         item_size = list->info.data_size;
10005         item_offset = list->info.desc_size;
10006         buffer = rsbac_vmalloc(item_size * list->count);
10007         if(buffer)
10008           {
10009             item_p = list->head;
10010             while(item_p)
10011               {
10012                 if(   !item_p->max_age
10013                    || (item_p->max_age > RSBAC_CURRENT_TIME)
10014                   )
10015                   {
10016                     memcpy(buffer + offset,
10017                            ((char *) item_p) + sizeof(*item_p) + item_offset,
10018                            item_size);
10019                     offset += item_size;
10020                     result++;
10021                   }
10022                 item_p = item_p->next;
10023               }
10024             *array_p = buffer;
10025           }
10026         else
10027           {
10028             result = -RSBAC_ENOMEM;
10029           }
10030       }
10031     rsbac_read_unlock(&list->lock, &lock_flags);
10032     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
10033     return result;
10034   }
10035 
10036 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10037 EXPORT_SYMBOL(rsbac_list_get_all_data);
10038 #endif
10039 long rsbac_list_get_all_data(
10040   rsbac_list_handle_t handle,
10041   void ** array_p)
10042   {
10043     return rsbac_ta_list_get_all_data(0, handle, array_p);
10044   }
10045 
10046 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10047 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_subdata);
10048 #endif
10049 long rsbac_ta_list_lol_get_all_subdata(
10050   rsbac_list_ta_number_t ta_number,
10051   rsbac_list_handle_t handle,
10052   void * desc,
10053   void ** array_p)
10054   {
10055     struct rsbac_list_lol_reg_item_t * list;
10056     struct rsbac_list_lol_item_t     * sublist;
10057     struct rsbac_list_item_t         * item_p;
10058            char                      * buffer;
10059     u_long lock_flags, rlock_flags;
10060     u_long offset = 0;
10061     long result = 0;
10062     u_int item_size;
10063     u_int item_offset;
10064 
10065     if(!handle)
10066       return -RSBAC_EINVALIDVALUE;
10067     if(!array_p)
10068       return -RSBAC_EINVALIDVALUE;
10069     if(!list_initialized)
10070       return -RSBAC_ENOTINITIALIZED;
10071 
10072     list = (struct rsbac_list_lol_reg_item_t *) handle;
10073     if(list->self != list)
10074       return -RSBAC_EINVALIDVALUE;
10075     *array_p = NULL;
10076 
10077 #ifdef CONFIG_RSBAC_LIST_TRANS
10078     if(ta_number)
10079       {
10080         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10081           return -RSBAC_EINVALIDTRANSACTION;
10082       }
10083 #endif
10084 
10085     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
10086 /*
10087 #ifdef CONFIG_RSBAC_DEBUG
10088     if(rsbac_debug_lists)
10089       rsbac_printk(KERN_DEBUG "rsbac_ta_list_lol_get_all_desc: list %s.\n",
10090              list->name);
10091 #endif
10092 */
10093     rsbac_read_lock(&list->lock, &lock_flags);
10094     if(!list->info.subdata_size)
10095       {
10096         rsbac_read_unlock(&list->lock, &lock_flags);
10097         rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10098         return -RSBAC_EINVALIDREQUEST;
10099       }
10100 #ifdef CONFIG_RSBAC_LIST_TRANS
10101     if(ta_number && (list->ta_copied == ta_number))
10102       sublist = ta_lookup_lol_item(ta_number, list, desc);
10103     else
10104 #endif
10105     sublist = lookup_lol_item(list, desc);
10106     if(sublist && sublist->count)
10107       {
10108         item_size = list->info.subdata_size;
10109         item_offset = list->info.subdesc_size;
10110         buffer = rsbac_vmalloc(item_size * sublist->count);
10111         if(buffer)
10112           {
10113             item_p = sublist->head;
10114             while(item_p)
10115               {
10116                 if(   !item_p->max_age
10117                    || (item_p->max_age > RSBAC_CURRENT_TIME)
10118                   )
10119                   {
10120                     memcpy(buffer + offset,
10121                            ((char *) item_p) + sizeof(*item_p) + item_offset,
10122                            item_size);
10123                     offset += item_size;
10124                     result++;
10125                   }
10126                 item_p = item_p->next;
10127               }
10128             *array_p = buffer;
10129           }
10130         else
10131           {
10132             result = -RSBAC_ENOMEM;
10133           }
10134       }
10135     rsbac_read_unlock(&list->lock, &lock_flags);
10136     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10137     return result;
10138   }
10139 
10140 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10141 EXPORT_SYMBOL(rsbac_list_lol_get_all_subdata);
10142 #endif
10143 long rsbac_list_lol_get_all_subdata(
10144   rsbac_list_handle_t handle,
10145   void * desc,
10146   void ** array_p)
10147   {
10148     return rsbac_ta_list_lol_get_all_subdata(0, handle, desc, array_p);
10149   }
10150 
10151 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10152 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_data);
10153 #endif
10154 long rsbac_ta_list_lol_get_all_data(
10155   rsbac_list_ta_number_t ta_number,
10156   rsbac_list_handle_t handle,
10157   void ** array_p)
10158   {
10159     struct rsbac_list_lol_reg_item_t * list;
10160     struct rsbac_list_lol_item_t     * item_p;
10161            char                      * buffer;
10162     u_long lock_flags, rlock_flags;
10163     u_long offset = 0;
10164     long result = 0;
10165     u_int item_size;
10166     u_int item_offset;
10167 
10168     if(!handle)
10169       return -RSBAC_EINVALIDVALUE;
10170     if(!array_p)
10171       return -RSBAC_EINVALIDVALUE;
10172     if(!list_initialized)
10173       return -RSBAC_ENOTINITIALIZED;
10174 
10175     list = (struct rsbac_list_lol_reg_item_t *) handle;
10176     if(list->self != list)
10177       return -RSBAC_EINVALIDVALUE;
10178     *array_p = NULL;
10179 
10180 #ifdef CONFIG_RSBAC_LIST_TRANS
10181     if(ta_number)
10182       {
10183         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10184           return -RSBAC_EINVALIDTRANSACTION;
10185       }
10186 #endif
10187 
10188     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
10189 /*
10190 #ifdef CONFIG_RSBAC_DEBUG
10191     if(rsbac_debug_lists)
10192       rsbac_printk(KERN_DEBUG "rsbac_list_lol_get_all_desc: list %s.\n",
10193              list->name);
10194 #endif
10195 */
10196     rsbac_read_lock(&list->lock, &lock_flags);
10197     if(!list->info.data_size)
10198       {
10199         rsbac_read_unlock(&list->lock, &lock_flags);
10200         rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10201         return -RSBAC_EINVALIDREQUEST;
10202       }
10203 #ifdef CONFIG_RSBAC_LIST_TRANS
10204     if(ta_number && (list->ta_copied == ta_number))
10205       {
10206         if(list->ta_count)
10207           {
10208             item_size = list->info.data_size;
10209             item_offset = list->info.desc_size;
10210             buffer = rsbac_vmalloc(item_size * list->ta_count);
10211             if(buffer)
10212               {
10213                 item_p = list->ta_head;
10214                 while(item_p)
10215                   {
10216                     if(   !item_p->max_age
10217                        || (item_p->max_age > RSBAC_CURRENT_TIME)
10218                       )
10219                       {
10220                         memcpy(buffer + offset,
10221                                ((char *) item_p) + sizeof(*item_p) + item_offset,
10222                                item_size);
10223                         offset += item_size;
10224                         result++;
10225                       }
10226                     item_p = item_p->next;
10227                   }
10228                 *array_p = buffer;
10229               }
10230             else
10231               {
10232                 result = -RSBAC_ENOMEM;
10233               }
10234           }
10235       }
10236     else
10237 #endif
10238     if(list->count)
10239       {
10240         item_size = list->info.data_size;
10241         item_offset = list->info.desc_size;
10242         buffer = rsbac_vmalloc(item_size * list->count);
10243         if(buffer)
10244           {
10245             item_p = list->head;
10246             while(item_p)
10247               {
10248                 if(   !item_p->max_age
10249                    || (item_p->max_age > RSBAC_CURRENT_TIME)
10250                   )
10251                   {
10252                     memcpy(buffer + offset,
10253                            ((char *) item_p) + sizeof(*item_p) + item_offset,
10254                            item_size);
10255                     offset += item_size;
10256                     result++;
10257                   }
10258                 item_p = item_p->next;
10259               }
10260             *array_p = buffer;
10261           }
10262         else
10263           {
10264             result = -RSBAC_ENOMEM;
10265           }
10266       }
10267     rsbac_read_unlock(&list->lock, &lock_flags);
10268     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10269     return result;
10270   }
10271 
10272 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10273 EXPORT_SYMBOL(rsbac_list_lol_get_all_data);
10274 #endif
10275 long rsbac_list_lol_get_all_data(
10276   rsbac_list_handle_t handle,
10277   void ** array_p)
10278   {
10279     return rsbac_ta_list_lol_get_all_data(0, handle, array_p);
10280   }
10281 
10282 /* Get item size */
10283 
10284 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10285 EXPORT_SYMBOL(rsbac_list_get_item_size);
10286 #endif
10287 int rsbac_list_get_item_size(rsbac_list_handle_t handle)
10288   {
10289     struct rsbac_list_reg_item_t * list;
10290 
10291     if(!handle)
10292       return -RSBAC_EINVALIDVALUE;
10293     if(!list_initialized)
10294       return -RSBAC_ENOTINITIALIZED;
10295 
10296     list = (struct rsbac_list_reg_item_t *) handle;
10297     if(list->self != list)
10298       return -RSBAC_EINVALIDVALUE;
10299     return list->info.desc_size + list->info.data_size;
10300   }
10301 
10302 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10303 EXPORT_SYMBOL(rsbac_list_lol_get_subitem_size);
10304 #endif
10305 int rsbac_list_lol_get_subitem_size(rsbac_list_handle_t handle)
10306   {
10307     struct rsbac_list_lol_reg_item_t * list;
10308 
10309     if(!handle)
10310       return -RSBAC_EINVALIDVALUE;
10311     if(!list_initialized)
10312       return -RSBAC_ENOTINITIALIZED;
10313 
10314     list = (struct rsbac_list_lol_reg_item_t *) handle;
10315     if(list->self != list)
10316       return -RSBAC_EINVALIDVALUE;
10317     return list->info.subdesc_size + list->info.subdata_size;
10318   }
10319 
10320 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10321 EXPORT_SYMBOL(rsbac_list_lol_get_item_size);
10322 #endif
10323 int rsbac_list_lol_get_item_size(rsbac_list_handle_t handle)
10324   {
10325     struct rsbac_list_lol_reg_item_t * list;
10326 
10327     if(!handle)
10328       return -RSBAC_EINVALIDVALUE;
10329     if(!list_initialized)
10330       return -RSBAC_ENOTINITIALIZED;
10331 
10332     list = (struct rsbac_list_lol_reg_item_t *) handle;
10333     if(list->self != list)
10334       return -RSBAC_EINVALIDVALUE;
10335     return list->info.desc_size + list->info.data_size;
10336   }
10337 
10338 /* Get array of all items */
10339 /* Returns number of items or negative error code */
10340 /* If return value > 0, *array_p contains a pointer to a rsbac_vmalloc'd array of items,
10341    where desc and data are placed directly behind each other.
10342    If *array_p has been set (return value > 0), caller must call rsbac_vfree(*array_p) after use! */
10343 
10344 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10345 EXPORT_SYMBOL(rsbac_ta_list_get_all_items_ttl);
10346 #endif
10347 long rsbac_ta_list_get_all_items_ttl(
10348   rsbac_list_ta_number_t ta_number,
10349   rsbac_list_handle_t handle,
10350   void ** array_p,
10351   rsbac_time_t ** ttl_array_p)
10352   {
10353     struct rsbac_list_reg_item_t * list;
10354     struct rsbac_list_item_t     * item_p;
10355            char                  * buffer;
10356            rsbac_time_t              * ttl_p = NULL;
10357     u_long lock_flags, rlock_flags;
10358     u_long offset = 0;
10359     long result = 0;
10360     u_int item_size;
10361 
10362     if(!handle)
10363       return -RSBAC_EINVALIDVALUE;
10364     if(!array_p)
10365       return -RSBAC_EINVALIDPOINTER;
10366     if(!list_initialized)
10367       return -RSBAC_ENOTINITIALIZED;
10368 
10369     list = (struct rsbac_list_reg_item_t *) handle;
10370     if(list->self != list)
10371       return -RSBAC_EINVALIDVALUE;
10372     *array_p = NULL;
10373 
10374 #ifdef CONFIG_RSBAC_LIST_TRANS
10375     if(ta_number)
10376       {
10377         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10378           return -RSBAC_EINVALIDTRANSACTION;
10379       }
10380 #endif
10381 
10382     rsbac_read_lock(&reg_head.lock, &rlock_flags);
10383 /*
10384 #ifdef CONFIG_RSBAC_DEBUG
10385     if(rsbac_debug_lists)
10386       rsbac_printk(KERN_DEBUG "rsbac_list_get_all_items: list %s.\n",
10387              list->name);
10388 #endif
10389 */
10390     rsbac_read_lock(&list->lock, &lock_flags);
10391 #ifdef CONFIG_RSBAC_LIST_TRANS
10392     if(ta_number && (list->ta_copied == ta_number))
10393       {
10394         if(list->ta_count)
10395           {
10396             item_size = list->info.desc_size + list->info.data_size;
10397             buffer = rsbac_vmalloc(item_size * list->ta_count);
10398             if(buffer)
10399               {
10400                 if(ttl_array_p)
10401                   ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * list->ta_count);
10402                 item_p = list->ta_head;
10403                 while(item_p)
10404                   {
10405                     if(   !item_p->max_age
10406                        || (item_p->max_age > RSBAC_CURRENT_TIME)
10407                       )
10408                       {
10409                         memcpy(buffer + offset,
10410                                ((char *) item_p) + sizeof(*item_p),
10411                                item_size);
10412                         if(ttl_p)
10413                           {
10414                             if(item_p->max_age)
10415                               ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME;
10416                             else
10417                               ttl_p[result] = 0;
10418                           }
10419                         offset += item_size;
10420                         result++;
10421                       }
10422                     item_p = item_p->next;
10423                   }
10424                 *array_p = buffer;
10425                 if(ttl_array_p)
10426                   *ttl_array_p = ttl_p;
10427               }
10428             else
10429               {
10430                 result = -RSBAC_ENOMEM;
10431               }
10432           }
10433       }
10434     else
10435 #endif
10436     if(list->count)
10437       {
10438         item_size = list->info.desc_size + list->info.data_size;
10439         buffer = rsbac_vmalloc(item_size * list->count);
10440         if(buffer)
10441           {
10442             if(ttl_array_p)
10443               ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * list->count);
10444             item_p = list->head;
10445             while(item_p)
10446               {
10447                 if(   !item_p->max_age
10448                    || (item_p->max_age > RSBAC_CURRENT_TIME)
10449                   )
10450                   {
10451                     memcpy(buffer + offset,
10452                            ((char *) item_p) + sizeof(*item_p),
10453                            item_size);
10454                     if(ttl_p)
10455                       {
10456                         if(item_p->max_age)
10457                           ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME;
10458                         else
10459                           ttl_p[result] = 0;
10460                       }
10461                     offset += item_size;
10462                     result++;
10463                   }
10464                 item_p = item_p->next;
10465               }
10466             *array_p = buffer;
10467             if(ttl_array_p)
10468               *ttl_array_p = ttl_p;
10469           }
10470         else
10471           {
10472             result = -RSBAC_ENOMEM;
10473           }
10474       }
10475     rsbac_read_unlock(&list->lock, &lock_flags);
10476     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
10477     return result;
10478   }
10479 
10480 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10481 EXPORT_SYMBOL(rsbac_list_get_all_items_ttl);
10482 #endif
10483 long rsbac_list_get_all_items_ttl(
10484   rsbac_list_handle_t handle,
10485   void ** array_p,
10486   rsbac_time_t ** ttl_array_p)
10487   {
10488     return rsbac_ta_list_get_all_items_ttl(0, handle, array_p, ttl_array_p);
10489   }
10490 
10491 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10492 EXPORT_SYMBOL(rsbac_list_get_all_items);
10493 #endif
10494 long rsbac_list_get_all_items(rsbac_list_handle_t handle, void ** array_p)
10495   {
10496     return rsbac_ta_list_get_all_items_ttl(0, handle, array_p, NULL);
10497   }
10498 
10499 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10500 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_subitems_ttl);
10501 #endif
10502 long rsbac_ta_list_lol_get_all_subitems_ttl(
10503   rsbac_list_ta_number_t ta_number,
10504   rsbac_list_handle_t handle,
10505   void * desc,
10506   void ** array_p,
10507   rsbac_time_t ** ttl_array_p)
10508   {
10509     struct rsbac_list_lol_reg_item_t * list;
10510     struct rsbac_list_lol_item_t     * sublist;
10511     struct rsbac_list_item_t         * item_p;
10512            char                      * buffer;
10513            rsbac_time_t              * ttl_p = NULL;
10514     u_long lock_flags, rlock_flags;
10515     u_long offset = 0;
10516     long result = 0;
10517     u_int item_size;
10518 
10519     if(!handle)
10520       return -RSBAC_EINVALIDVALUE;
10521     if(!array_p)
10522       return -RSBAC_EINVALIDVALUE;
10523     if(!list_initialized)
10524       return -RSBAC_ENOTINITIALIZED;
10525 
10526     list = (struct rsbac_list_lol_reg_item_t *) handle;
10527     if(list->self != list)
10528       return -RSBAC_EINVALIDVALUE;
10529     *array_p = NULL;
10530 
10531 #ifdef CONFIG_RSBAC_LIST_TRANS
10532     if(ta_number)
10533       {
10534         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10535           return -RSBAC_EINVALIDTRANSACTION;
10536       }
10537 #endif
10538 
10539     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
10540 /*
10541 #ifdef CONFIG_RSBAC_DEBUG
10542     if(rsbac_debug_lists)
10543       rsbac_printk(KERN_DEBUG "rsbac_list_lol_get_all_subitems: list %s.\n",
10544              list->name);
10545 #endif
10546 */
10547     rsbac_read_lock(&list->lock, &lock_flags);
10548 #ifdef CONFIG_RSBAC_LIST_TRANS
10549     if(ta_number && (list->ta_copied == ta_number))
10550       sublist = ta_lookup_lol_item(ta_number, list, desc);
10551     else
10552 #endif
10553     sublist = lookup_lol_item(list, desc);
10554     if(sublist && sublist->count)
10555       {
10556         item_size = list->info.subdesc_size + list->info.subdata_size;
10557         buffer = rsbac_vmalloc(item_size * sublist->count);
10558         if(buffer)
10559           {
10560             if(ttl_array_p)
10561               ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * sublist->count);
10562             item_p = sublist->head;
10563             while(item_p)
10564               {
10565                 if(   !item_p->max_age
10566                    || (item_p->max_age > RSBAC_CURRENT_TIME)
10567                   )
10568                   {
10569                     memcpy(buffer + offset,
10570                            ((char *) item_p) + sizeof(*item_p),
10571                            item_size);
10572                     if(ttl_p)
10573                       {
10574                         if(item_p->max_age)
10575                           ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME;
10576                         else
10577                           ttl_p[result] = 0;
10578                       }
10579                     offset += item_size;
10580                     result++;
10581                   }
10582                 item_p = item_p->next;
10583               }
10584             *array_p = buffer;
10585             if(ttl_array_p)
10586               *ttl_array_p = ttl_p;
10587           }
10588         else
10589           {
10590             result = -RSBAC_ENOMEM;
10591           }
10592       }
10593     rsbac_read_unlock(&list->lock, &lock_flags);
10594     rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10595     return result;
10596   }
10597 
10598 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10599 EXPORT_SYMBOL(rsbac_list_lol_get_all_subitems_ttl);
10600 #endif
10601 long rsbac_list_lol_get_all_subitems_ttl(
10602   rsbac_list_handle_t handle,
10603   void * desc,
10604   void ** array_p,
10605   rsbac_time_t ** ttl_array_p)
10606   {
10607     return rsbac_ta_list_lol_get_all_subitems_ttl(0, handle, desc,
10608                                                   array_p, ttl_array_p);
10609   }
10610 
10611 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10612 EXPORT_SYMBOL(rsbac_list_lol_get_all_subitems);
10613 #endif
10614 long rsbac_list_lol_get_all_subitems(rsbac_list_handle_t handle, void * desc, void ** array_p)
10615   {
10616     return rsbac_ta_list_lol_get_all_subitems_ttl(0, handle, desc,
10617                                                   array_p, NULL);
10618   }
10619 
10620 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10621 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_items);
10622 #endif
10623 long rsbac_ta_list_lol_get_all_items(
10624   rsbac_list_ta_number_t ta_number,
10625   rsbac_list_handle_t handle,
10626   void ** array_p)
10627   {
10628     struct rsbac_list_lol_reg_item_t * list;
10629     struct rsbac_list_lol_item_t     * item_p;
10630            char                      * buffer;
10631     u_long lock_flags, rlock_flags;
10632     u_long offset = 0;
10633     long result = 0;
10634     u_int item_size;
10635 
10636     if(!handle)
10637       return -RSBAC_EINVALIDVALUE;
10638     if(!array_p)
10639       return -RSBAC_EINVALIDVALUE;
10640     if(!list_initialized)
10641       return -RSBAC_ENOTINITIALIZED;
10642 
10643     list = (struct rsbac_list_lol_reg_item_t *) handle;
10644     if(list->self != list)
10645       return -RSBAC_EINVALIDVALUE;
10646     *array_p = NULL;
10647 
10648 #ifdef CONFIG_RSBAC_LIST_TRANS
10649     if(ta_number)
10650       {
10651         if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10652           return -RSBAC_EINVALIDTRANSACTION;
10653       }
10654 #endif
10655 
10656     rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
10657 /*
10658 #ifdef CONFIG_RSBAC_DEBUG
10659     if(rsbac_debug_lists)
10660       rsbac_printk(KERN_DEBUG "rsbac_list_lol_get_all_items: list %s.\n",
10661              list->name);
10662 #endif
10663 */
10664     rsbac_read_lock(&list->lock, &lock_flags);
10665 #ifdef CONFIG_RSBAC_LIST_TRANS
10666     if(ta_number && (list->ta_copied == ta_number))
10667       {
10668         if(list->ta_count)
10669           {
10670             item_size = list->info.desc_size + list->info.data_size;
10671             buffer = rsbac_vmalloc(item_size * list->ta_count);
10672             if(buffer)
10673               {
10674                 item_p = list->ta_head;
10675                 while(item_p)
10676                   {
10677                     if(   !item_p->max_age
10678                        || (item_p->max_age > RSBAC_CURRENT_TIME)
10679                       )
10680                       {
10681                         memcpy(buffer + offset,
10682                                ((char *) item_p) + sizeof(*item_p),
10683                                item_size);
10684                         offset += item_size;
10685                         result++;
10686                       }
10687                     item_p = item_p->next;
10688                   }
10689                 *array_p = buffer;
10690               }
10691             else
10692               {
10693                 result = -RSBAC_ENOMEM;
10694               }
10695           }
10696       }
10697     else
10698 #endif
10699     if(list->count)
10700       {
10701         item_size = list->info.desc_size + list->info.data_size;
10702         buffer = rsbac_vmalloc(item_size * list->count);
10703         if(buffer)
10704           {
10705             item_p = list->head;
10706             while(item_p)
10707               {
10708                 if(   !item_p->max_age
10709                    || (item_p->max_age > RSBAC_CURRENT_TIME)
10710                   )
10711                   {
10712                     memcpy(buffer + offset,
10713                            ((char *) item_p) + sizeof(*item_p),
10714                            item_size);
10715                     offset += item_size;
10716                     result++;
10717                   }
10718                 item_p = item_p->next;
10719               }
10720             *array_p = buffer;
10721           }
10722         else
10723           {
10724             result = -RSBAC_ENOMEM;
10725           }
10726       }
10727     rsbac_read_unlock(&list->lock, &lock_flags);
10728     rsbac_read_unlock(&reg_head.lock, &rlock_flags);
10729     return result;
10730   }
10731 
10732 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10733 EXPORT_SYMBOL(rsbac_list_lol_get_all_items);
10734 #endif
10735 long rsbac_list_lol_get_all_items(
10736   rsbac_list_handle_t handle,
10737   void ** array_p)
10738   {
10739     return rsbac_ta_list_lol_get_all_items(0, handle, array_p);
10740   }
10741 
10742 /* end of gen_lists.c */

Generated on Thu Sep 22 16:42:19 2005 for RSBAC by  doxygen 1.4.2