/*! \brief * Extract Address of Record */ int extract_aor(str* _uri, str* _a) { static char aor_buf[MAX_AOR_LEN]; memset(aor_buf, 0, MAX_AOR_LEN); str tmp; struct sip_uri puri; int user_len; if (parse_uri(_uri->s, _uri->len, &puri) < 0) { rerrno = R_AOR_PARSE; LM_ERR("failed to parse Address of Record\n"); return -1; } if ( (puri.user.len + puri.host.len + 1) > MAX_AOR_LEN || puri.user.len > USERNAME_MAX_SIZE || puri.host.len > DOMAIN_MAX_SIZE ) { rerrno = R_AOR_LEN; LM_ERR("Address Of Record too long\n"); return -2; } _a->s = aor_buf; _a->len = puri.user.len; if (un_escape(&puri.user, _a) < 0) { rerrno = R_UNESCAPE; LM_ERR("failed to unescape username\n"); return -3; } user_len = _a->len; if (reg_use_domain) { if (user_len) aor_buf[_a->len++] = '@'; /* strip prefix (if defined) */ if (realm_prefix.len && realm_prefix.len<puri.host.len && (memcmp(realm_prefix.s, puri.host.s, realm_prefix.len)==0) ) { memcpy(aor_buf + _a->len, puri.host.s + realm_prefix.len, puri.host.len - realm_prefix.len); _a->len += puri.host.len - realm_prefix.len; } else { memcpy(aor_buf + _a->len, puri.host.s, puri.host.len); _a->len += puri.host.len; } } if (case_sensitive && user_len) { tmp.s = _a->s + user_len + 1; tmp.len = _a->s + _a->len - tmp.s; strlower(&tmp); } else { strlower(_a); } return 0; }
/* * Extract Address of Record */ int extract_aor(str* _uri, str* _a) { static char aor_buf[MAX_AOR_LEN]; str tmp; struct sip_uri puri; int user_len; if (parse_uri(_uri->s, _uri->len, &puri) < 0) { rerrno = R_AOR_PARSE; LOG(L_ERR, "extract_aor(): Error while parsing Address of Record\n"); return -1; } if ((puri.user.len + puri.host.len + 1) > MAX_AOR_LEN) { rerrno = R_AOR_LEN; LOG(L_ERR, "extract_aor(): Address Of Record too long\n"); return -2; } _a->s = aor_buf; _a->len = puri.user.len; if (un_escape(&puri.user, _a) < 0) { rerrno = R_UNESCAPE; LOG(L_ERR, "extract_aor(): Error while unescaping username\n"); return -3; } user_len = _a->len; if (use_domain) { if (user_len) aor_buf[_a->len++] = '@'; /* strip prefix (if defined) */ if (realm_prefix.len && realm_prefix.len<puri.host.len && (memcmp(realm_prefix.s, puri.host.s, realm_prefix.len)==0) ) { memcpy(aor_buf + _a->len, puri.host.s + realm_prefix.len, puri.host.len - realm_prefix.len); _a->len += puri.host.len - realm_prefix.len; } else { memcpy(aor_buf + _a->len, puri.host.s, puri.host.len); _a->len += puri.host.len; } } if (case_sensitive && user_len) { tmp.s = _a->s + user_len + 1; tmp.len = _a->s + _a->len - tmp.s; strlower(&tmp); } else { strlower(_a); } return 0; }
/* * Authorize digest credentials */ static inline int authorize(struct sip_msg* _msg, pv_elem_t* _realm, pv_spec_t * _uri_user, int _hftype) { int res; auth_result_t ret; struct hdr_field* h; auth_body_t* cred; str *uri_user; str user, domain; pv_value_t pv_val; /* get pre_auth domain from _realm pvar (if exists) */ if (_realm) { if (pv_printf_s(_msg, _realm, &domain)!=0) { LM_ERR("pv_printf_s failed\n"); return AUTH_ERROR; } } else { /* get pre_auth domain from To/From header */ domain.len = 0; domain.s = 0; } ret = auth_api.pre_auth(_msg, &domain, _hftype, &h); if (ret != DO_AUTHORIZATION) return ret; cred = (auth_body_t*)h->parsed; /* get uri_user from _uri_user pvap (if exists) or from To/From URI */ if (_uri_user) { if (pv_get_spec_value(_msg, _uri_user, &pv_val) == 0) { if (pv_val.flags & PV_VAL_STR) { res = aaa_authorize_sterman(_msg, &cred->digest, &_msg->first_line.u.request.method, &pv_val.rs); } else { LM_ERR("uri_user pvar value is not string\n"); return AUTH_ERROR; } } else { LM_ERR("cannot get uri_user pvar value\n"); return AUTH_ERROR; } } else { if (get_uri_user(_msg, &uri_user) < 0) { LM_ERR("To/From URI not found\n"); return AUTH_ERROR; } user.s = (char *)pkg_malloc(uri_user->len); if (user.s == NULL) { LM_ERR("no pkg memory left for user\n"); return AUTH_ERROR; } un_escape(uri_user, &user); res = aaa_authorize_sterman(_msg, &cred->digest, &_msg->first_line.u.request.method, &user); pkg_free(user.s); } if (res == 1) { ret = auth_api.post_auth(_msg, h); return ret; } return AUTH_ERROR; }
/*! \brief * Extract Address of Record */ int extract_aor(str* _uri, str* _a) { static char aor_buf[MAX_AOR_LEN]; str tmp; struct sip_uri puri; int user_len; int_str avp_val; struct usr_avp *avp; str *uri; str realm_prefix; memset(aor_buf, 0, MAX_AOR_LEN); if (aor_avp_name.n != 0) { avp = search_first_avp(aor_avp_type, aor_avp_name, &avp_val, 0); if (avp && is_avp_str_val(avp)) { uri = &avp_val.s; } else { uri = _uri; } } else { uri = _uri; } if (parse_uri(uri->s, uri->len, &puri) < 0) { rerrno = R_AOR_PARSE; LM_ERR("failed to parse Address of Record\n"); return -1; } if ((puri.user.len + puri.host.len + 1 + 4) > MAX_AOR_LEN || puri.user.len > USERNAME_MAX_SIZE || puri.host.len > DOMAIN_MAX_SIZE) { rerrno = R_AOR_LEN; LM_ERR("Address Of Record too long\n"); return -2; } _a->s = aor_buf; _a->len = puri.user.len + 4; strncpy(_a->s, "sip:", 4); str tmps; tmps.s = _a->s + 4; tmps.len = puri.user.len; if (un_escape(&puri.user, &tmps) < 0) { rerrno = R_UNESCAPE; LM_ERR("failed to unescape username\n"); return -3; } user_len = tmps.len + 4;//_a->len; if (user_len>4) aor_buf[_a->len++] = '@'; /* strip prefix (if defined) */ realm_prefix.s = cfg_get(registrar, registrar_cfg, realm_pref); realm_prefix.len = strlen(realm_prefix.s); if (realm_prefix.len && realm_prefix.len < puri.host.len && (memcmp(realm_prefix.s, puri.host.s, realm_prefix.len) == 0)) { memcpy(aor_buf + _a->len, puri.host.s + realm_prefix.len, puri.host.len - realm_prefix.len); _a->len += puri.host.len - realm_prefix.len; } else { memcpy(aor_buf + _a->len, puri.host.s, puri.host.len); _a->len += puri.host.len; } if (cfg_get(registrar, registrar_cfg, case_sensitive) && user_len) { tmp.s = _a->s + user_len + 1; tmp.len = _a->s + _a->len - tmp.s; strlower(&tmp); } else { strlower(_a); } return 0; }
/* * Authorize digest credentials */ static inline int authorize(struct sip_msg* _msg, pv_elem_t* _realm, pv_spec_t * _uri_user, hdr_types_t _hftype) { int res; auth_cfg_result_t ret; struct hdr_field* h; auth_body_t* cred; str *uri_user; str user, domain; pv_value_t pv_val; cred = 0; ret = -1; user.s = 0; /* get pre_auth domain from _realm pvar (if exists) */ if (_realm) { if (pv_printf_s(_msg, _realm, &domain) != 0) { LM_ERR("pv_printf_s failed\n"); return -5; } } else { domain.len = 0; domain.s = 0; } switch(auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL)) { default: BUG("unexpected reply '%d'.\n", auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL)); #ifdef EXTRA_DEBUG abort(); #endif ret = -7; goto end; case NONCE_REUSED: ret = AUTH_NONCE_REUSED; goto end; case STALE_NONCE: ret = AUTH_STALE_NONCE; goto end; case ERROR: case BAD_CREDENTIALS: case NOT_AUTHENTICATED: ret = AUTH_ERROR; goto end; case NO_CREDENTIALS: ret = AUTH_NO_CREDENTIALS; goto end; case DO_AUTHENTICATION: break; case AUTHENTICATED: ret = AUTH_OK; goto end; } cred = (auth_body_t*)h->parsed; /* get uri_user from _uri_user pvap (if exists) or from To/From URI */ if (_uri_user) { if (pv_get_spec_value(_msg, _uri_user, &pv_val) == 0) { if (pv_val.flags & PV_VAL_STR) { res = radius_authorize_sterman(_msg, &cred->digest, &_msg-> first_line.u.request.method, &pv_val.rs); } else { LM_ERR("uri_user pvar value is not string\n"); ret = AUTH_ERROR; goto end; } } else { LM_ERR("cannot get uri_user pvar value\n"); ret = AUTH_ERROR; goto end; } } else { if (get_uri_user(_msg, &uri_user) < 0) { LM_ERR("To/From URI not found\n"); ret = AUTH_ERROR;; goto end; } user.s = (char *)pkg_malloc(uri_user->len); if (user.s == NULL) { LM_ERR("no pkg memory left for user\n"); ret = -7; goto end; } un_escape(uri_user, &user); res = radius_authorize_sterman(_msg, &cred->digest, &_msg->first_line.u.request.method, &user); } if (res == 1) { switch(auth_api.post_auth(_msg, h, NULL)) { default: BUG("unexpected reply '%d'.\n", auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL)); #ifdef EXTRA_DEBUG abort(); #endif ret = -7; break; case ERROR: case NOT_AUTHENTICATED: ret = AUTH_ERROR; break; case AUTHENTICATED: ret = AUTH_OK; break; } } else { ret = AUTH_INVALID_PASSWORD; } end: if (user.s) pkg_free(user.s); if (ret < 0) { if (auth_api.build_challenge(_msg, (cred ? cred->stale : 0), &domain, NULL, NULL, _hftype) < 0) { LM_ERR("while creating challenge\n"); ret = -7; } } return ret; }
/*! \brief * Extract Address of Record * In case of public GRUUs, also populates sip_instance * In case of temp GRUUs, also populates call_id */ int extract_aor(str* _uri, str* _a,str *sip_instance,str *call_id) { static char aor_buf[MAX_AOR_LEN]; memset(aor_buf, 0, MAX_AOR_LEN); str tmp; struct sip_uri puri; int user_len,tgruu_len,dec_size,i; str *magic; if (parse_uri(_uri->s, _uri->len, &puri) < 0) { rerrno = R_AOR_PARSE; LM_ERR("failed to parse Address of Record\n"); return -1; } /* if have ;gr param and func caller is interested in * potentially extracting the sip instance */ if ((puri.gr.s && puri.gr.len) && sip_instance) { LM_DBG("has gruu\n"); /* ;gr param detected */ if (memcmp(puri.user.s,TEMP_GRUU,TEMP_GRUU_SIZE) == 0) { LM_DBG("temp gruu\n"); /* temp GRUU, decode and extract aor, sip_instance * and call_id */ tgruu_len = puri.user.len - TEMP_GRUU_SIZE; memcpy(tgruu_dec,puri.user.s+TEMP_GRUU_SIZE,tgruu_len); if (gruu_secret.s != NULL) magic = &gruu_secret; else magic = &default_gruu_secret; dec_size = base64decode((unsigned char *)tgruu_dec, (unsigned char *)tgruu_dec,tgruu_len); for (i=0;i<tgruu_len;i++) tgruu_dec[i] ^= magic->s[i%magic->len]; LM_DBG("decoded [%.*s]\n",dec_size,tgruu_dec); /* extract aor - skip tgruu generation time at * the beggining */ _a->s = (char *)memchr(tgruu_dec,' ',dec_size) + 1; if (_a->s == NULL) { rerrno = R_AOR_PARSE; LM_ERR("failed to parse Address of Record\n"); return -1; } _a->len = (char *)memchr(_a->s,' ',dec_size - (_a->s-tgruu_dec)) - _a->s; if (_a->len < 0) { rerrno = R_AOR_PARSE; LM_ERR("failed to parse Address of Record\n"); return -1; } sip_instance->s = _a->s+_a->len+1; /* skip ' ' */ if (sip_instance->s >= tgruu_dec + dec_size) { rerrno = R_AOR_PARSE; LM_ERR("failed to parse Address of Record\n"); return -1; } sip_instance->len = (char *)memchr(sip_instance->s,' ', dec_size-(sip_instance->s-tgruu_dec)) - sip_instance->s; if (sip_instance->len < 0) { rerrno = R_AOR_PARSE; LM_ERR("failed to parse Address of Record\n"); return -1; } call_id->s = sip_instance->s + sip_instance->len + 1; if (call_id->s >= tgruu_dec + dec_size) { rerrno = R_AOR_PARSE; LM_ERR("failed to parse Address of Record\n"); return -1; } call_id->len = (tgruu_dec+dec_size) - call_id->s; LM_DBG("extracted aor [%.*s] and instance [%.*s] and callid [%.*s]\n",_a->len,_a->s, sip_instance->len,sip_instance->s,call_id->len,call_id->s); /* skip checks - done at save() */ return 0; } else { LM_DBG("public gruu\n"); *sip_instance = puri.gr_val; } } if ( (puri.user.len + puri.host.len + 1) > MAX_AOR_LEN || puri.user.len > USERNAME_MAX_SIZE || puri.host.len > DOMAIN_MAX_SIZE ) { rerrno = R_AOR_LEN; LM_ERR("Address Of Record too long\n"); return -2; } _a->s = aor_buf; _a->len = puri.user.len; if (un_escape(&puri.user, _a) < 0) { rerrno = R_UNESCAPE; LM_ERR("failed to unescape username\n"); return -3; } user_len = _a->len; if (reg_use_domain) { if (user_len) aor_buf[_a->len++] = '@'; /* strip prefix (if defined) */ if (realm_prefix.len && realm_prefix.len<puri.host.len && (memcmp(realm_prefix.s, puri.host.s, realm_prefix.len)==0) ) { memcpy(aor_buf + _a->len, puri.host.s + realm_prefix.len, puri.host.len - realm_prefix.len); _a->len += puri.host.len - realm_prefix.len; } else { memcpy(aor_buf + _a->len, puri.host.s, puri.host.len); _a->len += puri.host.len; } } if (case_sensitive && user_len) { tmp.s = _a->s + user_len + 1; tmp.len = _a->s + _a->len - tmp.s; strlower(&tmp); } else { strlower(_a); } return 0; }
/* * Authorize digest credentials */ static inline int authorize(struct sip_msg* _msg, str* _realm, int _hftype) { int res; auth_result_t ret; struct hdr_field* h; auth_body_t* cred; str* uri; struct sip_uri puri; str user, domain; domain = *_realm; ret = pre_auth_func(_msg, &domain, _hftype, &h); switch(ret) { case ERROR: return 0; case NOT_AUTHORIZED: return -1; case DO_AUTHORIZATION: break; case AUTHORIZED: return 1; } cred = (auth_body_t*)h->parsed; if (get_uri(_msg, &uri) < 0) { LOG(L_ERR, "authorize(): From/To URI not found\n"); return -1; } if (parse_uri(uri->s, uri->len, &puri) < 0) { LOG(L_ERR, "authorize(): Error while parsing From/To URI\n"); return -1; } if (puri.host.len != cred->digest.realm.len) { DBG("authorize(): Credentials realm and URI host do not match\n"); return -1; } if (strncasecmp(puri.host.s, cred->digest.realm.s, puri.host.len) != 0) { DBG("authorize(): Credentials realm and URI host do not match\n"); return -1; } user.s = (char *)pkg_malloc(puri.user.len); un_escape(&(puri.user), &user); /* Clear the rpid buffer from previous value */ rpid.len = 0; res = radius_authorize_sterman(_msg, &cred->digest, &_msg->first_line.u.request.method, &user, &rpid); pkg_free(user.s); if (res == 1) { ret = post_auth_func(_msg, h, &rpid); switch(ret) { case ERROR: return 0; case NOT_AUTHORIZED: return -1; case AUTHORIZED: return 1; default: return -1; } } return -1; }
/* * Authorize digest credentials */ static inline int authenticate(struct sip_msg* msg, str* realm, hdr_types_t hftype) { int res; auth_result_t ret; struct hdr_field* h; auth_body_t* cred; str* uri; struct sip_uri puri; str user, did; VALUE_PAIR* received; cred = 0; ret = -1; user.s = 0; received = NULL; switch(auth_api.pre_auth(msg, realm, hftype, &h, NULL)) { default: BUG("unexpected reply '%d'.\n", auth_api.pre_auth(msg, realm, hftype, &h, NULL)); #ifdef EXTRA_DEBUG abort(); #endif case ERROR: case BAD_CREDENTIALS: ret = -3; goto end; case NOT_AUTHENTICATED: ret = -1; goto end; case DO_AUTHENTICATION: break; case AUTHENTICATED: ret = 1; goto end; } cred = (auth_body_t*)h->parsed; if (use_did) { if (msg->REQ_METHOD == METHOD_REGISTER) { ret = get_to_did(&did, msg); } else { ret = get_from_did(&did, msg); } if (ret == 0) { did.s = DEFAULT_DID; did.len = sizeof(DEFAULT_DID) - 1; } } else { did.len = 0; did.s = 0; } if (get_uri(msg, &uri) < 0) { LOG(L_ERR, "authorize(): From/To URI not found\n"); ret = -1; goto end; } if (parse_uri(uri->s, uri->len, &puri) < 0) { LOG(L_ERR, "authorize(): Error while parsing From/To URI\n"); ret = -1; goto end; } user.s = (char *)pkg_malloc(puri.user.len); if (user.s == NULL) { LOG(L_ERR, "authorize: No memory left\n"); ret = -1; goto end; } un_escape(&(puri.user), &user); res = radius_authorize_sterman(&received, msg, &cred->digest, &msg->first_line.u.request.method, &user); if (res == 1) { switch(auth_api.post_auth(msg, h)) { case ERROR: case BAD_CREDENTIALS: ret = -2; break; case NOT_AUTHENTICATED: ret = -1; break; case AUTHENTICATED: if (generate_avps(received) < 0) { ret = -1; break; } ret = 1; break; default: ret = -1; break; } } else { ret = -1; } end: if (received) rc_avpair_free(received); if (user.s) pkg_free(user.s); if (ret < 0) { if (auth_api.build_challenge(msg, (cred ? cred->stale : 0), realm, NULL, NULL, hftype) < 0) { ERR("Error while creating challenge\n"); ret = -2; } } return ret; }
/*********************************************************************** * @todo Maybe invoice checking should be done in gnc_bi_import_fix_bis (...) * rather than in here? But that is more concerned with ensuring the csv is consistent. * @param GtkListStore *store * @param guint *n_invoices_created * @param guint *n_invoices_updated * @return void ***********************************************************************/ void gnc_bi_import_create_bis (GtkListStore * store, QofBook * book, guint * n_invoices_created, guint * n_invoices_updated, gchar * type, gchar * open_mode, GString * info) { gboolean valid; GtkTreeIter iter; gchar *id = NULL, *date_opened = NULL, *owner_id = NULL, *billing_id = NULL, *notes = NULL; gchar *date = NULL, *desc = NULL, *action = NULL, *account = NULL, *quantity = NULL, *price = NULL, *disc_type = NULL, *disc_how = NULL, *discount = NULL, *taxable = NULL, *taxincluded = NULL, *tax_table = NULL; gchar *date_posted = NULL, *due_date = NULL, *account_posted = NULL, *memo_posted = NULL, *accumulatesplits = NULL; guint dummy; GncInvoice *invoice; GncEntry *entry; gint day, month, year; gnc_numeric value; GncOwner *owner; Account *acc; enum update {YES = GTK_RESPONSE_YES, NO = GTK_RESPONSE_NO} update; GtkWidget *dialog; Timespec today; InvoiceWindow *iw; gchar *new_id = NULL; gint64 denom = 0; gnc_commodity *currency; // these arguments are needed g_return_if_fail (store && book); // logic of this function only works for bills or invoices g_return_if_fail ((g_ascii_strcasecmp (type, "INVOICE") == 0) || (g_ascii_strcasecmp (type, "BILL") == 0)); // allow to call this function without statistics if (!n_invoices_created) n_invoices_created = &dummy; if (!n_invoices_updated) n_invoices_updated = &dummy; *n_invoices_created = 0; *n_invoices_updated = 0; invoice = NULL; update = NO; valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter); while (valid) { // Walk through the list, reading each row gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, ID, &id, DATE_OPENED, &date_opened, DATE_POSTED, &date_posted, // if autoposting requested DUE_DATE, &due_date, // if autoposting requested ACCOUNT_POSTED, &account_posted, // if autoposting requested MEMO_POSTED, &memo_posted, // if autoposting requested ACCU_SPLITS, &accumulatesplits, // if autoposting requested OWNER_ID, &owner_id, BILLING_ID, &billing_id, NOTES, ¬es, DATE, &date, DESC, &desc, ACTION, &action, ACCOUNT, &account, QUANTITY, &quantity, PRICE, &price, DISC_TYPE, &disc_type, DISC_HOW, &disc_how, DISCOUNT, &discount, TAXABLE, &taxable, TAXINCLUDED, &taxincluded, TAX_TABLE, &tax_table, -1); // TODO: Assign a new invoice number if one is absent. BUT we don't want to assign a new invoice for every line!! // so we'd have to flag this up somehow or add an option in the import GUI. The former implies that we make // an assumption about what the importer (person) wants to do. It seems reasonable that a CSV file full of items with // If an invoice exists then we add to it in this current schema. // no predefined invoice number is a new invoice that's in need of a new number. // This was not designed to satisfy the need for repeat invoices however, so maybe we need a another method for this, after all // It should be easier to copy an invoice with a new ID than to go through all this malarky. if (g_ascii_strcasecmp (type, "BILL") == 0) invoice = gnc_search_bill_on_id (book, id); else if (g_ascii_strcasecmp (type, "INVOICE") == 0) invoice = gnc_search_invoice_on_id (book, id); DEBUG( "Existing %s ID: %s\n", type, gncInvoiceGetID(invoice)); // If the search is empty then there is no existing invoice so make a new one if (invoice == NULL) { DEBUG( "Creating a new : %s\n", type ); // new invoice invoice = gncInvoiceCreate (book); /* Protect against thrashing the DB and trying to write the invoice * record prematurely */ gncInvoiceBeginEdit (invoice); gncInvoiceSetID (invoice, id); owner = gncOwnerNew (); if (g_ascii_strcasecmp (type, "BILL") == 0) gncOwnerInitVendor (owner, gnc_search_vendor_on_id (book, owner_id)); else if (g_ascii_strcasecmp (type, "INVOICE") == 0) gncOwnerInitCustomer (owner, gnc_search_customer_on_id (book, owner_id)); gncInvoiceSetOwner (invoice, owner); gncInvoiceSetCurrency (invoice, gncOwnerGetCurrency (owner)); // Set the invoice currency based on the owner if (strlen (date_opened) != 0) // If a date is specified in CSV { // FIXME: Must check for the return value of qof_scan_date! qof_scan_date (date_opened, &day, &month, &year); gncInvoiceSetDateOpened (invoice, gnc_dmy2timespec (day, month, year)); } else // If no date in CSV { time64 now = gnc_time (NULL); Timespec now_timespec; timespecFromTime64 (&now_timespec, now); gncInvoiceSetDateOpened (invoice, now_timespec); } gncInvoiceSetBillingID (invoice, billing_id ? billing_id : ""); notes = un_escape(notes); gncInvoiceSetNotes (invoice, notes ? notes : ""); gncInvoiceSetActive (invoice, TRUE); //if (g_ascii_strcasecmp(type,"INVOICE"))gncInvoiceSetBillTo( invoice, billto ); (*n_invoices_created)++; update = YES; // open new bill / invoice in a tab, if requested if (g_ascii_strcasecmp(open_mode, "ALL") == 0 || (g_ascii_strcasecmp(open_mode, "NOT_POSTED") == 0 && strlen(date_posted) == 0)) { iw = gnc_ui_invoice_edit (invoice); gnc_plugin_page_invoice_new (iw); } gncInvoiceCommitEdit (invoice); } // I want to warn the user that an existing billvoice exists, but not every // time. // An import can contain many lines usually referring to the same invoice. // NB: Posted invoices are NEVER updated. else // if invoice exists { if (gncInvoiceIsPosted (invoice)) // Is it already posted? { valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter); continue; // If already posted then never import } if (update != YES) // Pop up a dialog to ask if updates are the expected action { dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_YES_NO, "%s", _("Are you sure you have bills/invoices to update?")); update = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); if (update == NO) { // Cleanup and leave g_free (id); g_free (date_opened); g_free (owner_id); g_free (billing_id); g_free (notes); g_free (date); g_free (desc); g_free (action); g_free (account); g_free (quantity); g_free (price); g_free (disc_type); g_free (disc_how); g_free (discount); g_free (taxable); g_free (taxincluded); g_free (tax_table); g_free (date_posted); g_free (due_date); g_free (account_posted); g_free (memo_posted); g_free (accumulatesplits); return; } } (*n_invoices_updated)++; } // add entry to invoice/bill entry = gncEntryCreate (book); gncEntryBeginEdit(entry); currency = gncInvoiceGetCurrency(invoice); if (currency) denom = gnc_commodity_get_fraction(currency); // FIXME: Must check for the return value of qof_scan_date! qof_scan_date (date, &day, &month, &year); { GDate *date = g_date_new_dmy(day, month, year); gncEntrySetDateGDate (entry, date); g_date_free (date); } timespecFromTime64 (&today, gnc_time (NULL)); // set today to the current date gncEntrySetDateEntered (entry, today); // Remove escaped quotes desc = un_escape(desc); notes = un_escape(notes); gncEntrySetDescription (entry, desc); gncEntrySetAction (entry, action); value = gnc_numeric_zero(); gnc_exp_parser_parse (quantity, &value, NULL); // Need to set the denom appropriately else we get stupid rounding errors. value = gnc_numeric_convert (value, denom * 100, GNC_HOW_RND_NEVER); //DEBUG("qty = %s",gnc_num_dbg_to_string(value)); gncEntrySetQuantity (entry, value); acc = gnc_account_lookup_for_register (gnc_get_current_root_account (), account); if (g_ascii_strcasecmp (type, "BILL") == 0) { gncEntrySetBillAccount (entry, acc); value = gnc_numeric_zero(); gnc_exp_parser_parse (price, &value, NULL); value = gnc_numeric_convert (value, denom * 100, GNC_HOW_RND_NEVER); gncEntrySetBillPrice (entry, value); gncEntrySetBillTaxable (entry, text2bool (taxable)); gncEntrySetBillTaxIncluded (entry, text2bool (taxincluded)); gncEntrySetBillTaxTable (entry, gncTaxTableLookupByName (book, tax_table)); gncEntryCommitEdit(entry); gncBillAddEntry (invoice, entry); } else if (g_ascii_strcasecmp (type, "INVOICE") == 0) { gncEntrySetNotes (entry, notes); gncEntrySetInvAccount (entry, acc); value = gnc_numeric_zero(); gnc_exp_parser_parse (price, &value, NULL); value = gnc_numeric_convert (value, denom * 100, GNC_HOW_RND_NEVER); //DEBUG("price = %s",gnc_num_dbg_to_string(value)); gncEntrySetInvPrice (entry, value); gncEntrySetInvTaxable (entry, text2bool (taxable)); gncEntrySetInvTaxIncluded (entry, text2bool (taxincluded)); gncEntrySetInvTaxTable (entry, gncTaxTableLookupByName (book, tax_table)); value = gnc_numeric_zero(); gnc_exp_parser_parse (discount, &value, NULL); value = gnc_numeric_convert (value, denom * 100, GNC_HOW_RND_NEVER); gncEntrySetInvDiscount (entry, value); gncEntrySetInvDiscountType (entry, text2disc_type (disc_type)); gncEntrySetInvDiscountHow (entry, text2disc_how (disc_how)); gncEntryCommitEdit(entry); gncInvoiceAddEntry (invoice, entry); } valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter); // handle auto posting of invoices new_id = NULL; if (valid) gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, ID, &new_id, -1); if (g_strcmp0 (id, new_id) != 0) { // the next invoice id is different => try to autopost this invoice if (qof_scan_date (date_posted, &day, &month, &year)) { // autopost this invoice gboolean auto_pay; Timespec d1, d2; if (g_ascii_strcasecmp (type, "INVOICE") == 0) auto_pay = gnc_prefs_get_bool (GNC_PREFS_GROUP_INVOICE, GNC_PREF_AUTO_PAY); else auto_pay = gnc_prefs_get_bool (GNC_PREFS_GROUP_BILL, GNC_PREF_AUTO_PAY); d1 = gnc_dmy2timespec (day, month, year); // FIXME: Must check for the return value of qof_scan_date! qof_scan_date (due_date, &day, &month, &year); // obtains the due date, or leaves it at date_posted d2 = gnc_dmy2timespec (day, month, year); acc = gnc_account_lookup_for_register (gnc_get_current_root_account (), account_posted); gncInvoicePostToAccount (invoice, acc, &d1, &d2, memo_posted, text2bool (accumulatesplits), auto_pay); DEBUG("Invoice %s posted",id); } } } // cleanup g_free (new_id); g_free (id); g_free (date_opened); g_free (owner_id); g_free (billing_id); g_free (notes); g_free (date); g_free (desc); g_free (action); g_free (account); g_free (quantity); g_free (price); g_free (disc_type); g_free (disc_how); g_free (discount); g_free (taxable); g_free (taxincluded); g_free (tax_table); g_free (date_posted); g_free (due_date); g_free (account_posted); g_free (memo_posted); g_free (accumulatesplits); }
/*! \brief * Extract Address of Record */ int extract_aor(str* _uri, str* _a, sip_uri_t *_pu) { static char aor_buf[MAX_AOR_LEN]; str tmp; sip_uri_t turi; sip_uri_t *puri; int user_len; str *uri; str realm_prefix = {0}; memset(aor_buf, 0, MAX_AOR_LEN); uri=_uri; if(_pu!=NULL) puri = _pu; else puri = &turi; if (parse_uri(uri->s, uri->len, puri) < 0) { rerrno = R_AOR_PARSE; LM_ERR("failed to parse AoR [%.*s]\n", uri->len, uri->s); return -1; } if ( (puri->user.len + puri->host.len + 1) > MAX_AOR_LEN || puri->user.len > USERNAME_MAX_SIZE || puri->host.len > DOMAIN_MAX_SIZE ) { rerrno = R_AOR_LEN; LM_ERR("Address Of Record too long\n"); return -2; } _a->s = aor_buf; _a->len = puri->user.len; if (un_escape(&puri->user, _a) < 0) { rerrno = R_UNESCAPE; LM_ERR("failed to unescape username\n"); return -3; } user_len = _a->len; if (reg_use_domain) { if (user_len) aor_buf[_a->len++] = '@'; /* strip prefix (if defined) */ realm_prefix.len = cfg_get(registrar, registrar_cfg, realm_pref).len; if(realm_prefix.len>0) { realm_prefix.s = cfg_get(registrar, registrar_cfg, realm_pref).s; LM_DBG("realm prefix is [%.*s]\n", realm_prefix.len, (realm_prefix.len>0)?realm_prefix.s:""); } if (realm_prefix.len>0 && realm_prefix.len<puri->host.len && (memcmp(realm_prefix.s, puri->host.s, realm_prefix.len)==0)) { memcpy(aor_buf + _a->len, puri->host.s + realm_prefix.len, puri->host.len - realm_prefix.len); _a->len += puri->host.len - realm_prefix.len; } else { memcpy(aor_buf + _a->len, puri->host.s, puri->host.len); _a->len += puri->host.len; } } if (cfg_get(registrar, registrar_cfg, case_sensitive) && user_len) { tmp.s = _a->s + user_len + 1; tmp.len = _a->s + _a->len - tmp.s; strlower(&tmp); } else { strlower(_a); } return 0; }