123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- /*
- * $Id$
- *
- * Usrloc module interface
- *
- * Copyright (C) 2001-2003 FhG Fokus
- *
- * This file is part of ser, a free SIP server.
- *
- * ser is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * For a license to use the ser software under conditions
- * other than those described here, or to purchase support for this
- * software, please contact iptel.org by e-mail at the following addresses:
- * [email protected]
- *
- * ser is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- #include <stdio.h>
- #include "../../dprint.h"
- #include "../../ut.h"
- #include "../../globals.h"
- #include "dlist.h"
- #include "utime.h"
- #include "ul_mod.h"
- #include "ul_rpc.h"
- static inline void rpc_find_domain(str* _name, udomain_t** _d)
- {
- dlist_t* ptr;
-
- ptr = root;
- while(ptr) {
- if ((ptr->name.len == _name->len) &&
- !memcmp(ptr->name.s, _name->s, _name->len)) {
- break;
- }
- ptr = ptr->next;
- }
-
- if (ptr) {
- *_d = ptr->d;
- } else {
- *_d = 0;
- }
- }
- static inline int add_contact(udomain_t* _d, str* _u, str* _c, time_t _e, qvalue_t _q, int _f, int sid)
- {
- urecord_t* r;
- ucontact_t* c = 0;
- int res;
- str cid;
- str ua;
- str aor = STR_NULL;
-
- if (_e == 0 && !(_f & FL_PERMANENT)) {
- LOG(L_ERR, "rpc_add_contact(): expires == 0 and not persistent contact, giving up\n");
- return -1;
- }
-
- get_act_time();
-
- res = get_urecord(_d, _u, &r);
- if (res < 0) {
- LOG(L_ERR, "rpc_add_contact(): Error while getting record\n");
- return -2;
- }
-
- if (res > 0) { /* Record not found */
- if (insert_urecord(_d, _u, &r) < 0) {
- LOG(L_ERR, "rpc_add_contact(): Error while creating new urecord\n");
- return -3;
- }
- } else {
- if (get_ucontact(r, _c, &c) < 0) {
- LOG(L_ERR, "rpc_add_contact(): Error while obtaining ucontact\n");
- return -4;
- }
- }
-
- cid.s = "RPC-Call-ID";
- cid.len = strlen(cid.s);
-
- ua.s = "SER-RPC";
- ua.len = strlen(ua.s);
-
- if (c) {
- if (update_ucontact(c, &aor, _c, _e + act_time, _q, &cid, 42, _f, FL_NONE, &ua, 0, 0, 0,
- sid == -1 ? server_id : sid) < 0) {
- LOG(L_ERR, "rpc_add_contact(): Error while updating contact\n");
- release_urecord(r);
- return -5;
- }
- } else {
- if (insert_ucontact(r, &aor, _c, _e + act_time, _q, &cid, 42, _f, &c, &ua, 0, 0, 0,
- sid == -1 ? server_id : sid) < 0) {
- LOG(L_ERR, "rpc_add_contact(): Error while inserting contact\n");
- release_urecord(r);
- return -6;
- }
- }
-
- release_urecord(r);
- return 0;
- }
- static const char* rpc_stats_doc[2] = {
- "Print usrloc statistics",
- 0
- };
- static void rpc_stats(rpc_t* rpc, void* c)
- {
- dlist_t* ptr;
- void* handle;
-
- ptr = root;
- while(ptr) {
- rpc->add(c, "{", &handle);
- rpc->struct_add(handle, "Sdd",
- "domain", ptr->d->name,
- "users", ptr->d->users,
- "expired", ptr->d->expired);
- ptr = ptr->next;
- }
- }
- static const char* rpc_delete_uid_doc[2] = {
- "Delete all registered contacts for address of record.",
- 0
- };
- static void rpc_delete_uid(rpc_t* rpc, void* c)
- {
- udomain_t* d;
- str uid, t;
-
- if (rpc->scan(c, "SS", &t, &uid) < 2) return;
-
- rpc_find_domain(&t, &d);
- if (d) {
- lock_udomain(d);
- if (delete_urecord(d, &uid) < 0) {
- ERR("Error while deleting user %.*s\n", uid.len, uid.s);
- unlock_udomain(d);
- rpc->fault(c, 500, "Error While Deleting Record");
- return;
- }
- unlock_udomain(d);
- } else {
- rpc->fault(c, 400, "Table Not Found");
- }
- }
- static const char* rpc_delete_contact_doc[2] = {
- "Delete a contact if it exists.",
- 0
- };
- static void rpc_delete_contact(rpc_t* rpc, void* ctx)
- {
- udomain_t* d;
- urecord_t* r;
- ucontact_t* con;
- str uid, t, c;
- int res;
-
- if (rpc->scan(ctx, "SSS", &t, &uid, &c) < 3) return;
-
- rpc_find_domain(&t, &d);
-
- if (d) {
- lock_udomain(d);
-
- res = get_urecord(d, &uid, &r);
- if (res < 0) {
- rpc->fault(ctx, 500, "Error While Searching Table");
- ERR("Error while looking for uid %.*s in table %.*s\n", uid.len, uid.s, t.len, t.s);
- unlock_udomain(d);
- return;
- }
-
- if (res > 0) {
- rpc->fault(ctx, 404, "AOR Not Found");
- unlock_udomain(d);
- return;
- }
-
- res = get_ucontact(r, &c, &con);
- if (res < 0) {
- rpc->fault(ctx, 500, "Error While Searching for Contact");
- ERR("Error while looking for contact %.*s\n", c.len, c.s);
- unlock_udomain(d);
- return;
- }
-
- if (res > 0) {
- rpc->fault(ctx, 404, "Contact Not Found");
- unlock_udomain(d);
- return;
- }
-
- if (delete_ucontact(r, con) < 0) {
- rpc->fault(ctx, 500, "Error While Deleting Contact");
- unlock_udomain(d);
- return;
- }
-
- release_urecord(r);
- unlock_udomain(d);
- } else {
- rpc->fault(ctx, 404, "Table Not Found");
- }
- }
- static const char* rpc_dump_doc[2] = {
- "Print all registered contacts.",
- 0
- };
- static void rpc_dump(rpc_t* rpc, void* c)
- {
- rpc->fault(c, 500, "Not Yet Implemented");
- }
- static const char* rpc_dump_file_doc[2] = {
- "Print all registered contacts into a file.",
- 0
- };
- static void rpc_dump_file(rpc_t* rpc, void* c)
- {
- str filename;
- FILE *file;
-
- if (rpc->scan(c, "S", &filename) < 1) {
- return;
- }
-
- DBG("dumping to file '%.*s'.\n", filename.len, ZSW(filename.s));
- if (! (file = fopen(filename.s, "w"))) {
- ERR("failed to open file `%s'.\n", filename.s);
- rpc->fault(rpc, 500, "failed to open file `%s'.\n", filename.s);
- return;
- }
- print_all_udomains(file);
- fclose(file);
- }
- static const char* rpc_flush_doc[2] = {
- "Flush cache into database.",
- 0
- };
- static void rpc_flush(rpc_t* rpc, void* c)
- {
- synchronize_all_udomains();
- }
- static const char* rpc_add_contact_doc[2] = {
- "Create a new contact.",
- 0
- };
- static void rpc_add_contact(rpc_t* rpc, void* c)
- {
- udomain_t* d;
- int expires, flags, sid;
- double q;
- qvalue_t qval;
-
- str table, uid, contact;
-
- if (rpc->scan(c, "SSSdfd", &table, &uid, &contact, &expires, &q, &flags) < 6) return;
- qval = double2q(q);
- if (rpc->scan(c, "d", &sid) < 1) sid = -1;
- rpc_find_domain(&table, &d);
- if (d) {
- lock_udomain(d);
-
- if (add_contact(d, &uid, &contact, expires, qval, flags, sid) < 0) {
- unlock_udomain(d);
- ERR("Error while adding contact ('%.*s','%.*s') in table '%.*s'\n",
- uid.len, ZSW(uid.s), contact.len, ZSW(contact.s), table.len, ZSW(table.s));
- rpc->fault(c, 500, "Error while adding Contact");
- return;
- }
- unlock_udomain(d);
- } else {
- rpc->fault(c, 400, "Table Not Found");
- }
- }
- /*
- * Build Contact HF for reply
- */
- static inline int print_contacts(rpc_t* rpc, void* ctx, ucontact_t* _c)
- {
- int cnt = 0;
- void* handle;
-
- while(_c) {
- if (VALID_CONTACT(_c, act_time)) {
- cnt++;
- if (rpc->add(ctx, "{", &handle) < 0) return -1;
- rpc->struct_add(handle, "SfdSS",
- "contact", &_c->c,
- "q", q2double(_c->q),
- "expires", (int)(_c->expires - act_time),
- "ua", &_c->user_agent,
- "recv", &_c->received);
- }
-
- _c = _c->next;
- }
-
- return cnt;
- }
- static const char* rpc_show_contacts_doc[2] = {
- "List all registered contacts for address of record",
- 0
- };
- static void rpc_show_contacts(rpc_t* rpc, void* c)
- {
- udomain_t* d;
- urecord_t* r;
- int res;
- str t, uid;
-
- if (rpc->scan(c, "SS", &t, &uid) < 2) return;
-
- rpc_find_domain(&t, &d);
- if (d) {
- lock_udomain(d);
-
- res = get_urecord(d, &uid, &r);
- if (res < 0) {
- rpc->fault(c, 500, "Error While Searching AOR");
- ERR("Error while looking for username %.*s in table %.*s\n", uid.len, uid.s, t.len, t.s);
- unlock_udomain(d);
- return;
- }
-
- if (res > 0) {
- rpc->fault(c, 404, "AOR Not Found");
- unlock_udomain(d);
- return;
- }
-
- get_act_time();
-
- if (!print_contacts(rpc, c, r->contacts)) {
- unlock_udomain(d);
- rpc->fault(c, 404, "No Registered Contacts Found");
- return;
- }
-
- unlock_udomain(d);
- } else {
- rpc->fault(c, 400, "Table Not Found");
- }
- }
- rpc_export_t ul_rpc[] = {
- {"usrloc.stats", rpc_stats, rpc_stats_doc, RET_ARRAY},
- {"usrloc.delete_uid", rpc_delete_uid, rpc_delete_uid_doc, 0},
- {"usrloc.delete_contact", rpc_delete_contact, rpc_delete_contact_doc, 0},
- {"usrloc.dump", rpc_dump, rpc_dump_doc, 0},
- {"usrloc.dump_file", rpc_dump_file, rpc_dump_file_doc, 0},
- {"usrloc.flush", rpc_flush, rpc_flush_doc, 0},
- {"usrloc.add_contact", rpc_add_contact, rpc_add_contact_doc, 0},
- {"usrloc.show_contacts", rpc_show_contacts, rpc_show_contacts_doc, RET_ARRAY},
- {0, 0, 0, 0}
- };
|