registrar_storage.c File Reference


Detailed Description

Serving-CSCF - Registrar Storage Operations.

Author:
Dragos Vingarzan vingarzan -at- fokus dot fraunhofer dot de

Definition in file registrar_storage.c.

#include <time.h>
#include "mod.h"
#include "registrar_storage.h"
#include "dlg_state.h"

Go to the source code of this file.

Defines

#define h_inc   h+=v^(v>>3)

Functions

void r_act_time ()
 Update the time.
int r_valid_contact (r_contact *c)
 Returns if a contact is valid.
int r_valid_subscriber (r_subscriber *s)
 Returns if a subscriber is valid (as in not expired).
unsigned int get_aor_hash (str aor, int hash_size)
 Computes the hash for a string.
int r_storage_init (int hash_size)
 Initialize the registrar.
void r_storage_destroy ()
 Destroy the registrar.
void r_lock (unsigned int hash)
 Lock a registrar hash slot.
void r_unlock (unsigned int hash)
 UnLock a registrar hash slot.
r_subscribernew_r_subscriber (str subscriber, int event, int expires, dlg_t *dialog)
 Creates a registrar public id subscriber This does not insert it in the registrar.
r_subscriberget_r_subscriber (r_public *p, str subscriber, int event)
 Searches for a r_subscriber subscriber and returns it.
r_subscriberadd_r_subscriber (r_public *p, str subscriber, int event, int expires, dlg_t *dialog)
 Adds a new subscriber to the list for the user.
r_subscriberupdate_r_subscriber (r_public *p, str subscriber, int event, int *expires, dlg_t *dialog)
 Updates the r_subscriber with the new expires value If not found, it will be inserted.
void del_r_subscriber (r_public *p, r_subscriber *s)
 Drops and deallocates a r_subscriber.
void free_r_subscriber (r_subscriber *s)
 Frees memory taken by a r_subscriber structure.
r_contactget_r_contact (r_public *p, str uri)
 Searches for a r_contact contact and returns it.
r_contactnew_r_contact (str uri, int expires, str ua, str path, qvalue_t qvalue)
 Creates a registrar contact.
r_contactadd_r_contact (r_public *p, str uri, int expires, str ua, str path, qvalue_t qvalue)
 Creates and Adds a new r_contact.
r_contactupdate_r_contact (r_public *p, str uri, int *expires, str *ua, str *path, qvalue_t qvalue)
 Updates the r_contact with the new expires, ua valu, path value.
void del_r_contact (r_public *p, r_contact *c)
 Drops and deallocates a r_contact.
void free_r_contact (r_contact *c)
 Frees memory taken by a r_contact structure.
void free_regexp_list (t_regexp_list **regexp)
char * escape_all_wildcards_and_copy (str wpsi)
r_publicnew_r_public (str aor, enum Reg_States reg_state, ims_subscription *s)
 In case of a Wildcarded PSI, it compiles the regexp for quick processing.
r_publicget_matching_wildcard_psi (str aor)
 Searches in the last hash slot (Wildcarded PSI) for a match on the aor within the regular expressions.
r_publicget_r_public (str aor)
 Searches for a r_public record and returns it.
r_publicget_r_public_wpsi (str pi)
int get_r_public_expires (str aor)
 Searches for a r_public record and returns its expiration value.
r_publicget_r_public_nolock (str aor)
 Searches for a r_public record and returns it.
r_publicget_r_public_previous_lock (str aor, int locked_hash)
 Searches for a r_public record and returns, with a previous lock aquired.
r_publicadd_r_public (str aor, enum Reg_States reg_state, ims_subscription *s)
 Creates and Adds a new r_public record.
r_publicadd_r_public_previous_lock (str aor, int locked_hash, enum Reg_States reg_state, ims_subscription *s)
 Creates and Adds a new r_public record with a previous lock already aquired.
r_publicupdate_r_public (str aor, enum Reg_States *reg_state, ims_subscription **s, str *ccf1, str *ccf2, str *ecf1, str *ecf2)
 Updates the r_public with the new reg_state and ims_subscription values.
r_publicupdate_r_public_previous_lock (str aor, int locked_hash, enum Reg_States *reg_state, ims_subscription **s, str *ccf1, str *ccf2, str *ecf1, str *ecf2)
 Updates the r_public with the new reg_state and ims_subscription values, with a previous lock on the registrar.
void r_public_expire (str public_id)
 Expires all the contacts for the given public id.
void r_private_expire (str private_id)
 Expires all the contacts of public identities that are related to the given private id.
void del_r_public (r_public *p)
 Drops and deallocates a r_public.
void free_r_public (r_public *p)
 Frees memory taken by a r_public aor structure.
void print_r (int log_level)
 Debug print the contents of the entire registrar.

Variables

tm_binds tmb
 Structure with pointers to tm funcs.
int scscf_support_wildcardPSI
int r_hash_size
 Size of S-CSCF registrar hash table.
r_hash_slotregistrar = 0
 The S-CSCF registrar.
time_t time_now
 Current time of the S-CSCF registrar.


Define Documentation

#define h_inc   h+=v^(v>>3)


Function Documentation

void r_act_time (  )  [inline]

Update the time.

Definition at line 109 of file registrar_storage.c.

References time_now.

00110 {
00111     time_now=time(0);
00112 }

int r_valid_contact ( r_contact c  )  [inline]

Returns if a contact is valid.

Caller should do actualization of time_now

Parameters:
c - the contact to check
Returns:
1 if valid, else 0

Definition at line 120 of file registrar_storage.c.

References DEREGISTERED, _r_contact::expires, NOT_REGISTERED, _r_contact::reg_state, and time_now.

00121 {
00122     return (c->expires>time_now);
00123 }

int r_valid_subscriber ( r_subscriber s  )  [inline]

Returns if a subscriber is valid (as in not expired).

Caller should do actualization of time_now

Parameters:
s - the contact to check
Returns:
1 if valid, else 0

Definition at line 131 of file registrar_storage.c.

References _r_subscriber::expires, and time_now.

Referenced by registrar_timer().

00132 {
00133     return (s->expires>time_now);
00134 }

unsigned int get_aor_hash ( str  aor,
int  hash_size 
) [inline]

Computes the hash for a string.

Parameters:
aor - the aor to compute the hash on
hash_size - value to % with
Returns:
the hash % hash_size

Definition at line 142 of file registrar_storage.c.

References h_inc.

Referenced by bin_decode_r_public(), get_r_public(), get_r_public_nolock(), get_r_public_previous_lock(), new_r_public(), and r_get_reginfo_full().

00143 {
00144 #define h_inc h+=v^(v>>3)
00145    char* p;
00146    register unsigned v;
00147    register unsigned h;
00148 
00149    h=0;
00150    for (p=aor.s; p<=(aor.s+aor.len-4); p+=4){
00151        v=(*p<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
00152        h_inc;
00153    }
00154    v=0;
00155    for (;p<(aor.s+aor.len); p++) {
00156        v<<=8;
00157        v+=*p;
00158    }
00159    h_inc;
00160 
00161    h=((h)+(h>>11))+((h>>13)+(h>>23));
00162    return (h)%hash_size;
00163 #undef h_inc 
00164 }

int r_storage_init ( int  hash_size  ) 

Initialize the registrar.

Parameters:
hash_size - number of hash slots to create
Returns:
1 on success, 0 on error

Definition at line 171 of file registrar_storage.c.

References r_hash_slot::lock, M_NAME, r_hash_size, and registrar.

00172 {
00173     int i;
00174     
00175     r_hash_size = hash_size;
00176     registrar = shm_malloc(sizeof(r_hash_slot)*(r_hash_size+1)); // 1 slot extra for the WildPSI
00177     memset(registrar,0,sizeof(r_hash_slot)*(r_hash_size+1));
00178     
00179     for(i=0;i<r_hash_size+1;i++){
00180         registrar[i].lock = lock_alloc();
00181         if (!registrar[i].lock){
00182             LOG(L_ERR,"ERR:"M_NAME":r_storage_init(): Error creating lock\n");
00183             return 0;
00184         }
00185         registrar[i].lock = lock_init(registrar[i].lock);
00186     }
00187             
00188     if (!registrar) return 0;
00189     
00190     return 1;
00191 }

void r_storage_destroy (  ) 

Destroy the registrar.

Definition at line 196 of file registrar_storage.c.

References free_r_contact(), free_r_public(), r_hash_slot::head, _r_contact::next, _r_public::next, r_hash_size, r_lock(), r_unlock(), and registrar.

00197 {
00198     int i;
00199     r_public *p,*np;
00200     for(i=0;i<r_hash_size+1;i++){
00201         r_lock(i);
00202             p = registrar[i].head;
00203             while(p){
00204                 np = p->next;
00205                 free_r_public(p);
00206                 p = np;
00207             }
00208         r_unlock(i);
00209         lock_dealloc(registrar[i].lock);
00210     }
00211     shm_free(registrar);
00212 }

void r_lock ( unsigned int  hash  )  [inline]

Lock a registrar hash slot.

Parameters:
hash - the index of the slot

Definition at line 219 of file registrar_storage.c.

References registrar.

00220 {
00221     // LOG(L_CRIT,"GET %d\n",hash);
00222     lock_get(registrar[(hash)].lock);
00223     // LOG(L_CRIT,"GOT %d\n",hash); 
00224 }

void r_unlock ( unsigned int  hash  )  [inline]

UnLock a registrar hash slot.

Parameters:
hash - the index of the slot

Definition at line 230 of file registrar_storage.c.

References registrar.

00231 {
00232     lock_release(registrar[(hash)].lock);
00233     // LOG(L_CRIT,"RELEASED %d\n",hash);    
00234 }

r_subscriber* new_r_subscriber ( str  subscriber,
int  event,
int  expires,
dlg_t *  dialog 
)

Creates a registrar public id subscriber This does not insert it in the registrar.

Parameters:
subscriber - the contact of the subscribption - the subscriber
event - what event to subscribe to
expires - time of expiration
dialog - dialog for the subscription
Returns:
the r_subscriber created, NULL on error

Definition at line 248 of file registrar_storage.c.

References _r_subscriber::dialog, _r_subscriber::event, _r_subscriber::expires, M_NAME, STR_SHM_DUP, and _r_subscriber::subscriber.

Referenced by add_r_subscriber().

00249 {
00250     r_subscriber *s;
00251     
00252     s = shm_malloc(sizeof(r_subscriber));
00253     if (!s) {
00254         LOG(L_ERR,"ERR:"M_NAME":new_r_subscriber(): Unable to alloc %d bytes\n",
00255             sizeof(r_subscriber));
00256         goto error;
00257     }
00258     memset(s,0,sizeof(r_subscriber));
00259     
00260     STR_SHM_DUP(s->subscriber,subscriber,"new_r_subscriber");
00261     
00262     s->event = event;
00263     
00264     s->expires = expires;
00265 
00266     s->dialog = dialog;
00267                     
00268     return s;
00269 error:
00270 out_of_memory:
00271     if (s){
00272         if (s->subscriber.s) shm_free(s->subscriber.s);
00273         shm_free(s);        
00274     }
00275     return 0;
00276 }

r_subscriber* get_r_subscriber ( r_public p,
str  subscriber,
int  event 
)

Searches for a r_subscriber subscriber and returns it.

Parameters:
p - the r_public record to look into
subscriber - the uri of the subscriber
event - what event to look for
Returns:
- the r_subscriber found, 0 if not found

Definition at line 286 of file registrar_storage.c.

References _r_subscriber::event, _r_subscriber::next, _r_public::shead, and _r_subscriber::subscriber.

Referenced by S_subscribe(), and update_r_subscriber().

00287 {
00288     r_subscriber *s=0;
00289     if (!p) return 0;
00290     s = p->shead;
00291     while(s){
00292         if (s->event == event &&
00293             s->subscriber.len == subscriber.len &&
00294             strncasecmp(s->subscriber.s,subscriber.s,subscriber.len)==0) return s;
00295         s = s->next;
00296     }
00297     return 0;
00298 }

r_subscriber* add_r_subscriber ( r_public p,
str  subscriber,
int  event,
int  expires,
dlg_t *  dialog 
)

Adds a new subscriber to the list for the user.

Note:
Make sure that get_r_subscriber(p,subscriber) returns 0 in order to avoid ureachable duplicates
Parameters:
p - the r_public to add to
subscriber - the contact of the subscribption - the subscriber
event - what event to subscribe to
expires - time of expiration
dialog - dialog for the subscription
Returns:
the r_subscriber that has been added, NULL on error

Definition at line 310 of file registrar_storage.c.

References new_r_subscriber(), _r_subscriber::next, _r_subscriber::prev, _r_public::shead, and _r_public::stail.

Referenced by update_r_subscriber().

00311 {
00312     r_subscriber *s;
00313 
00314     if (!p) return 0;
00315     
00316     s = new_r_subscriber(subscriber,event,expires,dialog);
00317     if (!s) return 0;       
00318     s->next = 0;
00319     s->prev = p->stail;
00320     if (p->stail) p->stail->next = s;
00321     p->stail = s;
00322     if (!p->shead) p->shead=s;
00323     
00324     return s;
00325 }

r_subscriber* update_r_subscriber ( r_public p,
str  subscriber,
int  event,
int *  expires,
dlg_t *  dialog 
)

Updates the r_subscriber with the new expires value If not found, it will be inserted.

Parameters:
p - the r_public to add to
subscriber - the subscriber to update
expires - new expires value, NULL if not necessary
ua - new user agent string, NULL if no update necessary
dialog - dialog for the subscription
Returns:
the newly added r_public, 0 on error

Definition at line 337 of file registrar_storage.c.

References add_r_subscriber(), _r_subscriber::dialog, _r_subscriber::expires, get_r_subscriber(), and tmb.

Referenced by S_subscribe().

00338 {
00339     r_subscriber *s;
00340     
00341     if (!p) return 0;
00342     s = get_r_subscriber(p,subscriber,event);
00343     if (!s){
00344         if (expires)
00345             return add_r_subscriber(p,subscriber,event,*expires,dialog);
00346         else return 0;
00347     }else{
00348         if (expires) s->expires = *expires;
00349         if (s->dialog && s->dialog!=dialog) tmb.free_dlg(s->dialog);
00350         s->dialog = dialog;
00351         return s;
00352     }
00353 }

void del_r_subscriber ( r_public p,
r_subscriber s 
)

Drops and deallocates a r_subscriber.

Note:
When calling be sure that get_r_subscriber(p,uri) returns c, to avoid a bogus removal.
Parameters:
p - the r_public record to look into
s - the r_subscriber to remove

Definition at line 361 of file registrar_storage.c.

References _r_subscriber::dialog, free_r_subscriber(), _r_subscriber::next, _r_subscriber::prev, _r_public::shead, _r_public::stail, and tmb.

Referenced by registrar_timer(), and S_subscribe().

00362 {
00363 //  LOG(L_ERR,"DBG:"M_NAME":del_r_subscriber: LIST: %p --> %p\n",p->shead,p->stail);
00364 //  LOG(L_ERR,"DBG:"M_NAME":del_r_subscriber: %p<- S:%p ->%p\n",s->prev,s,s->next); 
00365     if (p->shead == s) p->shead = s->next;
00366     else s->prev->next = s->next;
00367     if (p->stail == s) p->stail = s->prev;
00368     else s->next->prev = s->prev;
00369     if (s->dialog) tmb.free_dlg(s->dialog);
00370     
00371     free_r_subscriber(s);
00372 }

void free_r_subscriber ( r_subscriber s  ) 

Frees memory taken by a r_subscriber structure.

Parameters:
s - the r_contact to be deallocated

Definition at line 378 of file registrar_storage.c.

References _r_subscriber::subscriber.

Referenced by bin_decode_r_public(), del_r_subscriber(), and free_r_public().

00379 {
00380     if (!s) return;
00381     if (s->subscriber.s) shm_free(s->subscriber.s);
00382     shm_free(s);
00383 }

r_contact* get_r_contact ( r_public p,
str  uri 
)

Searches for a r_contact contact and returns it.

Parameters:
p - the r_public record to look into
uri - the uri of the contact
Returns:
- the r_contact found, 0 if not found

Definition at line 392 of file registrar_storage.c.

References _r_public::head, _r_contact::next, and _r_contact::uri.

00393 {
00394     r_contact *c=0;
00395     if (!p) return 0;
00396     c = p->head;
00397     while(c){
00398         if (c->uri.len == uri.len &&
00399             strncasecmp(c->uri.s,uri.s,uri.len)==0) return c;
00400         c = c->next;
00401     }
00402     return 0;
00403 }

r_contact* new_r_contact ( str  uri,
int  expires,
str  ua,
str  path,
qvalue_t  qvalue 
)

Creates a registrar contact.

This does not insert it in the registrar

Parameters:
uri - the contact uri
expires - the time of expiration
ua - the useragent string
path - Path header received at registration
qvalue - Q-value of the contact
Returns:
the new r_contact or NULL on error

Definition at line 415 of file registrar_storage.c.

References _r_contact::expires, M_NAME, _r_contact::path, _r_contact::qvalue, _r_contact::ua, and _r_contact::uri.

00416 {
00417     r_contact *c;
00418     
00419     c = shm_malloc(sizeof(r_contact));
00420     if (!c) {
00421         LOG(L_ERR,"ERR:"M_NAME":new_r_contact(): Unable to alloc %d bytes\n",
00422             sizeof(r_contact));
00423         goto error;
00424     }
00425     memset(c,0,sizeof(r_contact));
00426     
00427     c->uri.s = shm_malloc(uri.len);
00428     if (!c->uri.s){
00429         LOG(L_ERR,"ERR:"M_NAME":new_r_contact(): Unable to alloc %d bytes\n",
00430             uri.len);
00431         goto error;
00432     }   
00433     c->uri.len = uri.len;
00434     memcpy(c->uri.s,uri.s,uri.len);
00435     
00436     c->expires = expires;
00437     
00438     c->ua.s = shm_malloc(ua.len);
00439     if (!c->ua.s){
00440         LOG(L_ERR,"ERR:"M_NAME":new_r_contact(): Unable to alloc %d bytes\n",
00441             ua.len);
00442         goto error;
00443     }
00444     c->ua.len = ua.len;
00445     memcpy(c->ua.s,ua.s,ua.len);    
00446 
00447     if (path.len){
00448         c->path.s = shm_malloc(path.len);
00449         if (!c->path.s){
00450             LOG(L_ERR,"ERR:"M_NAME":new_r_contact(): Unable to alloc %d bytes\n",
00451                 path.len);
00452             goto error;
00453         }
00454         c->path.len = path.len;
00455         memcpy(c->path.s,path.s,path.len);  
00456     }
00457 
00458     c->qvalue = qvalue;
00459         
00460     return c;
00461 error:
00462     if (c){
00463         if (c->uri.s) shm_free(c->uri.s);
00464         if (c->ua.s) shm_free(c->ua.s);
00465         shm_free(c);
00466             
00467     }
00468     return 0;
00469 }

r_contact* add_r_contact ( r_public p,
str  uri,
int  expires,
str  ua,
str  path,
qvalue_t  qvalue 
)

Creates and Adds a new r_contact.

Note:
When calling be sure that get_r_contact(p,uri) returns 0, to avoid unreachable duplicates.
Parameters:
p - the r_public to add to
uri - the uri of the contact
expires - the expiration time
ua - the user agent string
path - Path header received at registration
qvalue - Q-value of the contact
Returns:
the newly added r_contact or NULL on error

Definition at line 482 of file registrar_storage.c.

References _r_public::head, new_r_contact(), _r_contact::next, _r_contact::prev, and _r_public::tail.

00483 {
00484     r_contact *c;
00485     if (!p) return 0;
00486     c = new_r_contact(uri,expires,ua,path,qvalue);
00487     if (!c) return 0;
00488     c->next=0;
00489     c->prev=p->tail;
00490     if (p->tail) {
00491         p->tail->next = c;
00492         p->tail = c;
00493     }
00494     else p->tail = c;
00495     if (!p->head) p->head=c;
00496     
00497     return c;
00498 }

r_contact* update_r_contact ( r_public p,
str  uri,
int *  expires,
str *  ua,
str *  path,
qvalue_t  qvalue 
)

Updates the r_contact with the new expires, ua valu, path value.

Note:
If not found it is added

Must be called with a lock on the hash slot to avoid races

Parameters:
p - the r_public to add to
uri - the contact uri
expires - new expires value, NULL if not necessary
ua - new user agent string, NULL if no update necessary
path - Path header received at registration
qvalue - Q-value of the contact
Returns:
the updated r_contact or NULL on error

Definition at line 512 of file registrar_storage.c.

References add_r_contact(), _r_contact::expires, get_r_contact(), M_NAME, _r_contact::path, _r_contact::qvalue, and _r_contact::ua.

00513 {
00514     r_contact *c;
00515     
00516     if (!p) return 0;
00517     c = get_r_contact(p,uri);
00518     if (!c){
00519         if (expires && ua && path)
00520             return add_r_contact(p,uri,*expires,*ua,*path,qvalue);
00521         else return 0;
00522     }else{
00523         if (expires) c->expires = *expires;
00524         if (ua){
00525             if (c->ua.s) shm_free(c->ua.s);
00526             c->ua.s = shm_malloc(ua->len);
00527             if (!c->ua.s) {
00528                 LOG(L_ERR,"ERR:"M_NAME":update_r_contact(): Error allocating %d bytes\n",
00529                     ua->len);
00530                 c->ua.len=0;
00531                 return 0;
00532             }
00533             c->ua.len = ua->len;
00534             memcpy(c->ua.s,ua->s,ua->len);
00535         }
00536         if (path){
00537             if (c->path.s) shm_free(c->path.s);
00538             c->path.s = shm_malloc(path->len);
00539             if (!c->path.s) {
00540                 LOG(L_ERR,"ERR:"M_NAME":update_r_contact(): Error allocating %d bytes\n",
00541                     path->len);
00542                 c->path.len=0;
00543                 return 0;
00544             }
00545             c->path.len = path->len;
00546             memcpy(c->path.s,path->s,path->len);
00547         }
00548         c->qvalue = qvalue;
00549         return c;
00550     }
00551 }

void del_r_contact ( r_public p,
r_contact c 
)

Drops and deallocates a r_contact.

Note:
When calling be sure that get_r_contact(p,uri) returns c, to avoid a bogus removal
Parameters:
p - the r_public record to look into
c - the r_contact to remove

Definition at line 559 of file registrar_storage.c.

References free_r_contact(), _r_public::head, _r_contact::next, _r_contact::prev, and _r_public::tail.

00560 {
00561     if (p->head == c) p->head = c->next;
00562     else c->prev->next = c->next;
00563     if (p->tail == c) p->tail = c->prev;
00564     else c->next->prev = c->prev;
00565     free_r_contact(c);
00566 }

void free_r_contact ( r_contact c  ) 

Frees memory taken by a r_contact structure.

Parameters:
c - the r_contact to be deallocated

Definition at line 571 of file registrar_storage.c.

References free_r_public(), free_r_security(), _r_contact::head, _r_contact::host, if, _r_public::next, _r_contact::path, _r_contact::pinhole, _r_contact::security, _r_contact::security_temp, _r_contact::service_route, _r_contact::service_route_cnt, _r_contact::ua, and _r_contact::uri.

00572 {
00573     if (!c) return;
00574     if (c->uri.s) shm_free(c->uri.s);
00575     if (c->ua.s) shm_free(c->ua.s);
00576     if (c->path.s) shm_free(c->path.s);
00577     shm_free(c);
00578 }

void free_regexp_list ( t_regexp_list **  regexp  ) 

Definition at line 1283 of file registrar_storage.c.

References _t_regexp_unit::next, and _t_regexp_unit::s.

Referenced by free_r_public().

01284 {
01285     t_regexp_unit *un,*dos;
01286     
01287     un=(*regexp)->head;
01288         while (un)
01289         {
01290             dos=un->next;
01291             if (un->s) shm_free(un->s);
01292             //if (1) regfree(&(un->exp));
01293             shm_free(un);
01294             un=dos;
01295         }
01296         shm_free(*regexp);
01297     
01298 }

char* escape_all_wildcards_and_copy ( str  wpsi  ) 

Definition at line 591 of file registrar_storage.c.

Referenced by new_r_public().

00592 {
00593     char *res;
00594     int i,j,len;
00595     len=1+wpsi.len; // the \0
00596     j=0;
00597     //first lets see how many wildcards there are to see how much space is needed
00598     for (i=0;i<wpsi.len;i++)
00599     {
00600         switch(wpsi.s[i])
00601         {
00602             case '?': case '*':// case '.':
00603                 len++;
00604                 break;
00605         }
00606     }
00607     res=shm_malloc(len);
00608     // then do the copy
00609     for (i=0;i<wpsi.len;i++)
00610     {
00611         switch(wpsi.s[i]) {
00612             case '.':
00613                 res[j++]='\\';
00614                 res[j++]=wpsi.s[i];
00615                 break;
00616             case '?' : case '*':
00617                 res[j++]='.';
00618             default :
00619                 res[j++]=wpsi.s[i]; 
00620                 break;
00621         }
00622     }
00623     res[j]=0;
00624     return res;
00625 }

r_public* new_r_public ( str  aor,
enum Reg_States  reg_state,
ims_subscription s 
)

In case of a Wildcarded PSI, it compiles the regexp for quick processing.

Definition at line 638 of file registrar_storage.c.

References escape_all_wildcards_and_copy(), get_aor_hash(), _r_public::hash, _t_regexp_list::head, M_NAME, _t_regexp_unit::next, NULL, _t_regexp_unit::prev, ims_service_profile::public_identities, ims_service_profile::public_identities_cnt, r_hash_size, _r_public::regexp, _t_regexp_unit::s, ims_subscription::service_profiles, ims_subscription::service_profiles_cnt, _t_regexp_list::tail, ims_public_identity::wildcarded_psi, and ims_subscription::wpsi.

00639 {
00640     r_public *p;
00641     
00642     /*I didn't want to make this so complicated..*/
00643     t_regexp_unit *newwpsi;
00644     char *temp=0;
00645     int i,j;
00646     //int len;
00647     //int errcode;
00648     
00649     p = shm_malloc(sizeof(r_public));
00650     if (!p){
00651         LOG(L_ERR,"ERR:"M_NAME":new_r_public(): Unable to alloc %d bytes\n",
00652             sizeof(r_public));
00653         goto error;
00654     }   
00655     memset(p,0,sizeof(r_public));
00656     if (s->wpsi !=1)
00657     {
00658         //very sensible thing to do...
00659         p->hash = get_aor_hash(aor,r_hash_size);
00660         
00661     } else {
00662         
00663         //here it gets a bit complicated
00664         
00665         /* if its a wildcarded psi....*/
00666         p->hash=r_hash_size;
00667         /*will be in the last slot*/
00668         p->regexp=shm_malloc(sizeof(t_regexp_list));
00669         p->regexp->head=NULL;
00670         p->regexp->tail=NULL;
00671         /*lets compile the regular expression and compile it..*/
00672         for (i=0;i<s->service_profiles_cnt;i++)
00673         {
00674             for (j=0;j<s->service_profiles[i].public_identities_cnt;j++)
00675             {
00676                 if (s->service_profiles[i].public_identities[j].wildcarded_psi.s && s->service_profiles[i].public_identities[j].wildcarded_psi.len>0)
00677                  {
00678                     // for each wildcardpsi we add a member to the regexp list in the r_public
00679                     newwpsi=shm_malloc(sizeof(t_regexp_unit));
00680                     newwpsi->next=NULL;
00681                     newwpsi->prev=NULL;
00682                     // now we have to deal with using an external function that expects
00683                     // some string with a finishing \0 character
00684                     //len=s->service_profiles[i].public_identities[j].wildcarded_psi.len;
00685                     temp=escape_all_wildcards_and_copy(s->service_profiles[i].public_identities[j].wildcarded_psi);
00686                     //temp=shm_malloc(len+1);
00687                     //memcpy(temp,s->service_profiles[i].public_identities[j].wildcarded_psi.s,len);
00688                     //temp[len]=0;
00689                     LOG(L_DBG,"New_r_public : REGULAR EXPRESSION is %s\n\n",temp);
00690                     /*errcode=regcomp(&(newwpsi->exp),temp,REG_ICASE|REG_EXTENDED|REG_NOSUB);
00691                     if(errcode!=0)
00692                     {
00693                         // there was an error
00694                         LOG(L_DBG,"there was at least ONE error in regcomp %i\n",errcode);
00695                         //shm_free(temp); temp=NULL;
00696                         len=regerror(errcode,&(newwpsi->exp),NULL,0);
00697                         temp=shm_malloc(len);
00698                         regerror(errcode,&(newwpsi->exp),temp,len);
00699                         LOG(L_DBG,"and that was %s",temp);
00700                         shm_free(temp); temp=NULL;
00701                         
00702                         shm_free(newwpsi);
00703                         goto error;
00704                     }*/
00705                     newwpsi->s=temp;
00706                     //LOG(L_DBG,"there was NO error in regcomp\n");
00707                     //shm_free(temp); temp=NULL;
00708                     newwpsi->prev=p->regexp->tail;
00709                     if (p->rege