📄 ul_unixsock.c
字号:
/* * $Id: ul_unixsock.c,v 1.5.2.1 2005/03/29 11:54:35 janakj Exp $ * * Copyright (C) 2004 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: * info@iptel.org * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */#include "../../unixsock_server.h"#include "../../ut.h"#include "../../str.h"#include "../../qvalue.h"#include "dlist.h"#include "ul_mod.h"#include "ul_fifo.h"#include "utime.h"#include "ul_unixsock.h"/* * Dedicated to Douglas Adams, don't panic ! */#define UNIXSOCK_CALLID "The-Answer-To-The-Ultimate-Question-Of-Life-Universe-And-Everything"#define UNIXSOCK_CALLID_LEN (sizeof(UNIXSOCK_CALLID)-1)#define UNIXSOCK_CSEQ 42#define UNIXSOCK_UA "SIP Express Router UNIXSOCK"#define UNIXSOCK_UA_LEN (sizeof(UNIXSOCK_UA)-1)static inline int add_contact(udomain_t* _d, str* _u, str* _c, time_t _e, qvalue_t _q, int _f){ urecord_t* r; ucontact_t* c = 0; int res; str cid, ua; if (_e == 0 && !(_f & FL_PERMANENT)) { LOG(L_ERR, "fifo_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, "fifo_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, "fifo_add_contact(): Error while creating new urecord\n"); return -3; } } else { if (get_ucontact(r, _c, &c) < 0) { LOG(L_ERR, "fifo_add_contact(): Error while obtaining ucontact\n"); return -4; } } cid.s = UNIXSOCK_CALLID; cid.len = UNIXSOCK_CALLID_LEN; ua.s = UNIXSOCK_UA; ua.len = UNIXSOCK_UA_LEN; if (c) { if (update_ucontact(c, _e + act_time, _q, &cid, UNIXSOCK_CSEQ, _f, FL_NONE, &ua, 0) < 0) { LOG(L_ERR, "fifo_add_contact(): Error while updating contact\n"); release_urecord(r); return -5; } } else { if (insert_ucontact(r, _c, _e + act_time, _q, &cid, UNIXSOCK_CSEQ, _f, &c, &ua, 0) < 0) { LOG(L_ERR, "fifo_add_contact(): Error while inserting contact\n"); release_urecord(r); return -6; } } release_urecord(r); return 0;}static inline void unixsock_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 int ul_stats_cmd(str* msg){ dlist_t* ptr; unixsock_reply_asciiz("200 OK\n"); unixsock_reply_asciiz("Domain Registered Expired\n"); ptr = root; while(ptr) { if (unixsock_reply_printf("'%.*s' %d %d\n", ptr->d->name->len, ZSW(ptr->d->name->s), ptr->d->users, ptr->d->expired ) < 0) { unixsock_reply_reset(); unixsock_reply_asciiz("500 Buffer Too Small\n"); unixsock_reply_send(); return -1; } ptr = ptr->next; } unixsock_reply_send(); return 0;}static int ul_rm(str* msg){ udomain_t* d; str table, user; char* at; if (unixsock_read_line(&table, msg) != 0) { unixsock_reply_asciiz("400 Table name expected\n"); goto err; } if (unixsock_read_line(&user, msg) != 0) { unixsock_reply_asciiz("400 User name expected\n"); goto err; } at = q_memchr(user.s, '@', user.len); if (use_domain) { if (!at) { unixsock_reply_asciiz("400 Domain missing\n"); goto err; } } else { if (at) { user.len = at - user.s; } } strlower(&user); unixsock_find_domain(&table, &d); LOG(L_INFO, "INFO: Deleting entry (%.*s,%.*s)\n", table.len, ZSW(table.s), user.len, ZSW(user.s)); if (d) { lock_udomain(d); if (delete_urecord(d, &user) < 0) { LOG(L_ERR, "ul_rm(): Error while deleting user %.*s\n", user.len, ZSW(user.s)); unlock_udomain(d); unixsock_reply_printf("500 Error while deleting user %.*s\n", user.len, ZSW(user.s)); goto err; } unlock_udomain(d); unixsock_reply_printf("200 user (%.*s, %.*s) deleted\n", table.len, ZSW(table.s), user.len, ZSW(user.s)); unixsock_reply_send(); return 0; } else { unixsock_reply_printf("400 table (%.*s) not found\n", table.len, ZSW(table.s)); return 0; } err: unixsock_reply_send(); return -1;}static int ul_rm_contact(str* msg){ udomain_t* d; urecord_t* r; ucontact_t* con; str table, user, contact; int res; char* at; if (unixsock_read_line(&table, msg) != 0) { unixsock_reply_asciiz("400 Table name expected\n"); goto err; } if (unixsock_read_line(&user, msg) != 0) { unixsock_reply_asciiz("400 Username expected\n"); goto err; } at = q_memchr(user.s, '@', user.len); if (use_domain) { if (!at) { unixsock_reply_asciiz("400 Domain missing\n"); goto err; } } else { if (at) { user.len = at - user.s; } } if (unixsock_read_line(&contact, msg) != 0) { unixsock_reply_asciiz("400 Contact expected\n"); goto err; } strlower(&user); unixsock_find_domain(&table, &d); LOG(L_INFO, "INFO: Deleting contact (%.*s,%.*s,%.*s)\n", table.len, ZSW(table.s), user.len, ZSW(user.s), contact.len, ZSW(contact.s)); if (d) { lock_udomain(d); res = get_urecord(d, &user, &r); if (res < 0) { unixsock_reply_printf("500 Error while looking for username %.*s in table %.*s\n", user.len, ZSW(user.s), table.len, ZSW(table.s)); goto err_unlock; } if (res > 0) { unixsock_reply_printf("404 Username %.*s in table %.*s not found\n", user.len, ZSW(user.s), table.len, ZSW(table.s)); goto err_unlock; } res = get_ucontact(r, &contact, &con); if (res < 0) { unixsock_reply_printf("500 Error while looking for contact %.*s\n", contact.len, ZSW(contact.s)); goto err_unlock; } if (res > 0) { unixsock_reply_printf("404 Contact %.*s in table %.*s not found\n", contact.len, ZSW(contact.s), table.len, ZSW(table.s)); goto err_unlock; } if (delete_ucontact(r, con) < 0) { unixsock_reply_printf("500 ul_rm_contact: Error while deleting contact %.*s\n", contact.len, ZSW(contact.s)); goto err_unlock; } release_urecord(r); unlock_udomain(d); unixsock_reply_printf("200 Contact (%.*s, %.*s) deleted from table %.*s\n", user.len, ZSW(user.s), contact.len, ZSW(contact.s), table.len, ZSW(table.s)); unixsock_reply_send(); return 0; } else { unixsock_reply_printf("400 table (%.*s) not found\n", table.len, ZSW(table.s)); goto err; } err_unlock: unlock_udomain(d); err: unixsock_reply_send(); return -1;}static int ul_flush(str* msg){ synchronize_all_udomains(); unixsock_reply_printf("200 ul_flush completed\n"); unixsock_reply_send(); return 0;}static int ul_dump(str* msg){ /* This function is not implemented in unixsock interface, * it produces a lot of data which would not fit into a single * message */ unixsock_reply_asciiz( "500 Not Implemented\n"); return 0;}static int ul_add(str* msg){ udomain_t* d; qvalue_t qval; int exp_i, flags_i; char* at; str table, user, contact, expires, q, rep, flags; if (unixsock_read_line(&table, msg) != 0) { unixsock_reply_asciiz("400 Table name expected\n"); goto err; } if (unixsock_read_line(&user, msg) != 0) { unixsock_reply_asciiz("400 AOR name expected\n"); goto err; } at = q_memchr(user.s, '@', user.len); if (use_domain) { if (!at) { unixsock_reply_asciiz("400 Username@domain expected\n"); goto err; } } else { if (at) { user.len = at - user.s; } } if (unixsock_read_line(&contact, msg) != 0) { unixsock_reply_asciiz("400 Contact expected\n"); goto err; } if (unixsock_read_line(&expires, msg) != 0) { unixsock_reply_asciiz("400 Expires expected\n"); goto err; } if (unixsock_read_line(&q, msg) != 0) { unixsock_reply_asciiz("400 q value expected\n"); goto err; } /* Kept for backwards compatibility */ if (unixsock_read_line(&rep, msg) != 0) { unixsock_reply_asciiz("400 Replicate expected\n"); goto err; } if (unixsock_read_line(&flags, msg) != 0) { unixsock_reply_asciiz("400 Flags expected\n"); goto err; } strlower(&user); unixsock_find_domain(&table, &d); if (d) { if (str2int(&expires, (unsigned int*)&exp_i) < 0) { unixsock_reply_asciiz("400 Invalid expires format\n"); goto err; } if (str2q(&qval, q.s, q.len) < 0) { unixsock_reply_asciiz("400 invalid q value\n"); goto err; } if (str2int(&flags, (unsigned int*)&flags_i) < 0) { unixsock_reply_asciiz("400 Invalid flags format\n"); goto err; } lock_udomain(d); if (add_contact(d, &user, &contact, exp_i, qval, flags_i) < 0) { unlock_udomain(d); LOG(L_ERR, "ul_add(): Error while adding contact ('%.*s','%.*s') in table '%.*s'\n", user.len, ZSW(user.s), contact.len, ZSW(contact.s), table.len, ZSW(table.s)); unixsock_reply_printf("500 Error while adding contact\n" " ('%.*s','%.*s') in table '%.*s'\n", user.len, ZSW(user.s), contact.len, ZSW(contact.s), table.len, ZSW(table.s)); goto err; } unlock_udomain(d); unixsock_reply_printf("200 Added to table\n" "('%.*s','%.*s') to '%.*s'\n", user.len, ZSW(user.s), contact.len, ZSW(contact.s), table.len, ZSW(table.s)); unixsock_reply_send(); return 0; } else { unixsock_reply_printf("400 Table '%.*s' not found in memory, use save(\"%.*s\") or lookup(\"%.*s\") in the configuration script first\n", table.len, ZSW(table.s), table.len, ZSW(table.s), table.len, ZSW(table.s)); unixsock_reply_send(); return 0; } err: unixsock_reply_send(); return -1;}/* * Build Contact HF for reply */static inline int print_contacts(ucontact_t* _c){ int cnt = 0; while(_c) { if (VALID_CONTACT(_c, act_time)) { cnt++; if (cnt == 1) { unixsock_reply_asciiz("200 OK\n"); } if (unixsock_reply_printf("<%.*s>;q=%s;expires=%d\n", _c->c.len, ZSW(_c->c.s), q2str(_c->q, 0), (int)(_c->expires - act_time)) < 0) { return -1; } } _c = _c->next; } return cnt == 0;}static inline int ul_show_contact(str* msg){ udomain_t* d; urecord_t* r; int res; str table, aor; char* at; if (unixsock_read_line(&table, msg) != 0) { unixsock_reply_asciiz("400 Table name expected\n"); goto err; } if (unixsock_read_line(&aor, msg) != 0) { unixsock_reply_asciiz("400 Address of Record expected\n"); goto err; } at = q_memchr(aor.s, '@', aor.len); if (use_domain) { if (!at) { unixsock_reply_asciiz("400 User@domain expected\n"); goto err; } } else { if (at) { aor.len = at - aor.s; } } strlower(&aor); unixsock_find_domain(&table, &d); if (d) { lock_udomain(d); res = get_urecord(d, &aor, &r); if (res < 0) { unixsock_reply_printf("500 Error while looking for username %.*s in table %.*s\n", aor.len, ZSW(aor.s), table.len, ZSW(table.s)); goto err_unlock; } if (res > 0) { unixsock_reply_printf("404 Username %.*s in table %.*s not found\n", aor.len, ZSW(aor.s), table.len, ZSW(table.s)); goto err_unlock; } get_act_time(); res = print_contacts(r->contacts); if (res > 0) { unixsock_reply_asciiz("404 No registered contacts found\n"); res = 1; } else if (res < 0) { unixsock_reply_reset(); unixsock_reply_asciiz("500 Buffer too small\n"); goto err_unlock; } else { res = 0; } unlock_udomain(d); unixsock_reply_send(); return res; } else { unixsock_reply_printf("400 table (%.*s) not found\n", table.len, ZSW(table.s)); goto err; } err_unlock: unlock_udomain(d); err: unixsock_reply_send(); return -1;}int init_ul_unixsock(void) { if (unixsock_register_cmd(UL_STATS, ul_stats_cmd) < 0) { LOG(L_CRIT, "init_ul_unixsock: cannot register ul_stats\n"); return -1; } if (unixsock_register_cmd(UL_RM, ul_rm) < 0) { LOG(L_CRIT, "init_ul_unixsock: cannot register ul_rm\n"); return -1; } if (unixsock_register_cmd(UL_RM_CONTACT, ul_rm_contact) < 0) { LOG(L_CRIT, "init_ul_unixsock: cannot register ul_rm_contact\n"); return -1; } if (unixsock_register_cmd(UL_DUMP, ul_dump) < 0) { LOG(L_CRIT, "init_ul_unixsock: cannot register ul_dump\n"); return -1; } if (unixsock_register_cmd(UL_FLUSH, ul_flush) < 0) { LOG(L_CRIT, "init_ul_unixsock: cannot register ul_flush\n"); return -1; } if (unixsock_register_cmd(UL_ADD, ul_add) < 0) { LOG(L_CRIT, "init_ul_unixsock: cannot register ul_add\n"); return -1; } if (unixsock_register_cmd(UL_SHOW_CONTACT, ul_show_contact) < 0) { LOG(L_CRIT, "init_ul_unixsock: cannot register ul_show_contact\n"); return -1; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -