static int replace(char *buf, int size, const char * pattern, char *rp) { regex_t regex; int regex_error; if ((regex_error = regcomp(®ex, pattern, REG_EXTENDED)) != 0) { char buffer[1024]; regerror(regex_error, ®ex, buffer, sizeof(buffer)); fatal("Error compiling REGEX: %s", buffer); } else if (rreplace(buf, size, ®ex, rp)) { fatal("Error doing regex replace"); } else { regfree(®ex); } return 0; }
/* private plugin code */ static int plugin_regex_redirect(sip_ticket_t *ticket) { osip_uri_t *to_url=ticket->sipmsg->to->url; char *url_string=NULL; osip_uri_t *new_to_url; int i, sts; osip_contact_t *contact = NULL; /* character workspaces for regex */ #define WORKSPACE_SIZE 128 static char in[WORKSPACE_SIZE+1], rp[WORKSPACE_SIZE+1]; /* do apply to full To URI... */ sts = osip_uri_to_str(to_url, &url_string); if (sts != 0) { ERROR("osip_uri_to_str() failed"); return STS_FAILURE; } DEBUGC(DBCLASS_BABBLE, "To URI string: [%s]", url_string); /* perform search and replace of the regexes, first match hits */ for (i = 0; i < plugin_cfg.regex_pattern.used; i++) { regmatch_t *pmatch = NULL; pmatch = rmatch(url_string, WORKSPACE_SIZE, &re[i]); if (pmatch == NULL) continue; /* no match, next */ /* have a match, do the replacement */ INFO("Matched rexec rule: %s",plugin_cfg.regex_desc.string[i] ); strncpy (in, url_string, WORKSPACE_SIZE); in[WORKSPACE_SIZE]='\0'; strncpy (rp, plugin_cfg.regex_replace.string[i], WORKSPACE_SIZE); rp[WORKSPACE_SIZE]='\0'; sts = rreplace(in, WORKSPACE_SIZE, &re[i], pmatch, rp); if (sts != STS_SUCCESS) { ERROR("regex replace failed: pattern:[%s] replace:[%s]", plugin_cfg.regex_pattern.string[i], plugin_cfg.regex_replace.string[i]); osip_free(url_string); return STS_FAILURE; } /* only do first match */ break; } if (i >= plugin_cfg.regex_pattern.used) { /* no match */ osip_free(url_string); return STS_SUCCESS; } /* in: contains the new string */ sts = osip_uri_init(&new_to_url); if (sts != 0) { ERROR("Unable to initialize URI"); osip_free(url_string); return STS_FAILURE; } sts = osip_uri_parse(new_to_url, in); if (sts != 0) { ERROR("Unable to parse To URI: %s", in); osip_uri_free(new_to_url); osip_free(url_string); return STS_FAILURE; } /* use a "302 Moved temporarily" response back to the client */ /* new target is within the Contact Header */ /* remove all Contact headers in message */ for (i=0; (contact != NULL) || (i == 0); i++) { osip_message_get_contact(ticket->sipmsg, 0, &contact); if (contact) { osip_list_remove(&(ticket->sipmsg->contacts),0); osip_contact_free(contact); } } /* for i */ /* insert one new Contact header containing the new target address */ osip_contact_init(&contact); osip_list_add(&(ticket->sipmsg->contacts),contact,0); /* link the new_to_url into the Contact list */ contact->url = new_to_url; new_to_url = NULL; /* * Add the 'REDIRECTED_TAG=REDIRECTED_VAL' parameter to URI. Required to figure out * if this INVITE has already been processed (redirected) and * does not need further attention by this plugin. * THIS IS REQUIRED TO AVOID A LOOP */ osip_uri_param_add(&(contact->url->url_params), osip_strdup(REDIRECTED_TAG), osip_strdup(REDIRECTED_VAL)); INFO("redirecting %s -> %s", url_string, in); /* sent redirect message back to local client */ add_to_redirected_cache(&redirected_cache, ticket); sip_gen_response(ticket, 302 /*Moved temporarily*/); /* release resources and return */ osip_free(url_string); return STS_SIP_SENT; }