📄 userdb.c
字号:
#include <stdio.h>#include <string.h>#include <errno.h>#include <gnome.h>#include <glib.h>#include "callbacks.h"#include "common.h"static GList *users=NULL;static GList *waiter_windows=NULL;GStaticMutex userdb_mutex = G_STATIC_MUTEX_INIT;GStaticMutex win_mutex = G_STATIC_MUTEX_INIT;static gint userdb_find_element(gconstpointer a,gconstpointer b) { int rc=-EINVAL; userdb_t *user_a,*user_b; if ( (!a) || (!b) ) goto out; user_a=(userdb_t *)a; user_b=(userdb_t *)b; if ( (!strncmp(user_a->user,user_b->user,NAME_LEN)) && (!strcmp(user_a->ipaddr,user_b->ipaddr)) ) { rc=0; goto out; /* found */ } rc=1; out: return rc; /* Not found */}static gint userdb_find_by_ipaddr(gconstpointer a,gconstpointer b) { int rc=-EINVAL; userdb_t *user_a,*user_b; if ( (!a) || (!b) ) goto out; user_a=(userdb_t *)a; user_b=(userdb_t *)b; if (!strcmp(user_a->ipaddr,user_b->ipaddr)) return 0; rc=-ESRCH; out: return rc; /* Not found */}static voidprint_one_user_entry(gpointer data,gpointer user_data) { userdb_t *current_user; if (!data) return; current_user=(userdb_t *)data; dbg_out("NickName: %s\n",current_user->nickname); dbg_out("Group: %s\n",current_user->group); dbg_out("User: %s\n",current_user->user); dbg_out("Host: %s\n",current_user->host); dbg_out("IP Addr: %s\n",current_user->ipaddr); dbg_out("Capability: %x\n",(unsigned int)current_user->cap); if (current_user->cap & IPMSG_DIALUPOPT) dbg_out("\t Dialup host\n"); if (current_user->cap & IPMSG_FILEATTACHOPT) dbg_out("\t File Attach\n"); if (current_user->cap & IPMSG_ENCRYPTOPT) dbg_out("\t Encryption\n"); return;}static intalloc_user_info(userdb_t **entry){ userdb_t *new_user; if (!entry) return -EINVAL; new_user=g_slice_new(userdb_t); if (!new_user) return -ENOMEM; memset(new_user,0,sizeof(userdb_t)); *entry=new_user; return 0;}static intdestroy_user_info_contents(userdb_t *entry){ if (!entry) return -EINVAL; if (entry->user) free(entry->user); if (entry->host) free(entry->host); if (entry->group) free(entry->group); if (entry->nickname) free(entry->nickname); if (entry->ipaddr) free(entry->ipaddr); memset(entry,0,sizeof(userdb_t)); return 0;}static voiddo_notify_change(gpointer data,gpointer user_data) { GtkWidget *window; if (!data) return; window=GTK_WIDGET(data); update_users_on_message_window(window); return;}static intnotify_userdb_changed(void){ g_static_mutex_lock(&win_mutex); g_list_foreach(waiter_windows, do_notify_change, NULL); g_static_mutex_unlock(&win_mutex);}#define strdup_with_check(dest,src,member,err_label) \ ((dest)->member)=strdup((src)->member); \ if (!((dest)->member)) \ goto err_label ; static intcopy_user_info(userdb_t *dest,userdb_t *src) { int rc=-ENOMEM; if ( (!dest) || (!src) ) return -EINVAL; g_assert(!(dest->user)); g_assert(!(dest->host)); g_assert(!(dest->group)); g_assert(!(dest->nickname)); g_assert(!(dest->ipaddr)); /* 下記はマクロであることに注意 */ strdup_with_check(dest,src,user,err_out) strdup_with_check(dest,src,host,err_out) strdup_with_check(dest,src,group,err_out) strdup_with_check(dest,src,nickname,err_out) strdup_with_check(dest,src,ipaddr,err_out) return 0; err_out: destroy_user_info_contents(dest); return rc;}static intfill_user_info_with_message(const char *peer_addr,const msg_data_t *msg,userdb_t *new_user){ int rc; if ( (!new_user) || (!msg) ) return -EINVAL; memset(new_user,0,sizeof(userdb_t)); rc=-ENOMEM; convert_string_internal(refer_user_name_from_msg(msg),(const gchar **)&(new_user->user)); if (!(new_user->user)) goto free_slice_out; convert_string_internal(refer_host_name_from_msg(msg),(const gchar **)&(new_user->host)); if (!(new_user->host)) goto free_user_out; convert_string_internal(refer_group_name_from_msg(msg),(const gchar **)&(new_user->group)); if (!(new_user->group)) goto free_host_out; convert_string_internal(refer_nick_name_from_msg(msg),(const gchar **)&(new_user->nickname)); if (!(new_user->nickname)) goto free_nickname_out; convert_string_internal(peer_addr,(const gchar **)&(new_user->ipaddr)); if (!(new_user->ipaddr)) goto free_group_out; new_user->cap=msg->command_opts; dbg_out("Add: %s %s %s %s %x\n", new_user->user, new_user->host, new_user->group, new_user->ipaddr, (unsigned int)new_user->cap); return 0; free_ipaddr_out: g_free(new_user->ipaddr); free_nickname_out: g_free(new_user->nickname); free_group_out: g_free(new_user->group); free_host_out: g_free(new_user->host); free_user_out: g_free(new_user->user); free_slice_out: dbg_out("Free: %x\n",(unsigned int)new_user); g_slice_free(userdb_t,new_user); return rc;}static intadd_with_userdb_entry(userdb_t *new_user){ int rc; GList *new_entry; if (!new_user) return -EINVAL; dbg_out("Add: %s %s %s %s %x\n", new_user->user, new_user->host, new_user->group, new_user->ipaddr, (unsigned int)new_user->cap); g_static_mutex_lock(&userdb_mutex); if (!g_list_find_custom (users,new_user,userdb_find_element)) users=g_list_append(users,new_user); else { rc=-EEXIST; g_static_mutex_unlock(&userdb_mutex); destroy_user_info(new_user); return rc; } rc=0; /* * 健全性チェック */ new_entry=g_list_find_custom(users,new_user,userdb_find_element); _assert(new_entry); _assert(new_entry->data == new_user); g_static_mutex_unlock(&userdb_mutex); notify_userdb_changed(); return rc;}/* *start:length:ユーザ名:ホスト名:コマンド番号:IP アドレス: *ポート番号(リトルエンディアン):ニックネーム:グループ名 */static intuserdb_add_hostlist_entry(userdb_t *entry,const char **entry_string_p, int *is_last){ int rc; char *buffer=NULL; char *sp,*ep; long remains; int intval; size_t len; char *user=NULL; char *host=NULL; char *ipaddr=NULL; int port; char *nickname=NULL; char *group=NULL; const char *entry_string; if ( (!entry) || (!entry_string_p) || (!is_last) ) return -EINVAL; entry_string=*entry_string_p; rc=-ENOMEM; buffer=strdup(entry_string); if (!buffer) goto free_buffer_out; rc=-ENOENT; *is_last=1; len=strlen(buffer); remains=len; dbg_out("Buffer:%s\n",buffer); /* * username */ sp=buffer; ep=memchr(sp, HOSTLIST_SEPARATOR, remains); if (!ep) goto free_buffer_out; remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_buffer_out; *ep='\0'; user=strdup(make_entry_canonical(sp)); if (!user) goto free_buffer_out; ++ep; sp=ep; dbg_out("user:%s\n",user); /* * host */ ep=memchr(sp, HOSTLIST_SEPARATOR, remains); if (!ep) goto free_user_out; remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_user_out; *ep='\0'; host=strdup(make_entry_canonical(sp)); if (!host) goto free_user_out; ++ep; sp=ep; dbg_out("host:%s\n",host); /* * skip command */ ep=memchr(sp, HOSTLIST_SEPARATOR , remains); if (!ep) goto free_host_out; remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_host_out; *ep='\0'; ++ep; sp=ep; /* * ipaddr */ ep=memchr(sp, HOSTLIST_SEPARATOR, remains); if (!ep) goto free_host_out; remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_host_out; *ep='\0'; ipaddr=strdup(make_entry_canonical(sp)); if (!ipaddr) goto free_host_out; ++ep; sp=ep; dbg_out("ipaddr:%s\n",ipaddr); /* * port */ ep=memchr(sp, HOSTLIST_SEPARATOR , remains); if (!ep) goto free_ipaddr_out; remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_ipaddr_out; *ep='\0'; intval=strtol(sp, (char **)NULL, 10); ++ep; sp=ep; dbg_out("port:%d\n",intval); /* * nick name */ ep=memchr(sp, HOSTLIST_SEPARATOR , remains); if (!ep) goto free_ipaddr_out; remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_ipaddr_out; *ep='\0'; nickname=strdup(make_entry_canonical(sp)); if (!nickname) goto free_ipaddr_out; ++ep; sp=ep; dbg_out("nickname:%s\n",nickname); /* * group */ ep=memchr(sp, HOSTLIST_SEPARATOR , remains); if (!ep) { ep=memchr(sp, '\0' , remains); if (!ep) goto free_nickname_out; }else{ *is_last=0; } remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_nickname_out; *ep='\0'; group=strdup(make_entry_canonical(sp)); if (!nickname) goto free_nickname_out; ++ep; dbg_out("group:%s\n",group); entry->user=user; entry->host=host; entry->group=group; entry->nickname=nickname; entry->ipaddr=ipaddr; entry->cap=IPMSG_DIALUPOPT; /* ダイアルアップとみなす */ dbg_out("OK entry:\nuser : %s\nhost :%s\ngroup : %s\nnickname : %s\nipaddr : %s\n", entry->user=user, entry->host=host, entry->group=group, entry->nickname=nickname, entry->ipaddr=ipaddr); rc=add_with_userdb_entry(entry); *entry_string_p=sp; dbg_out("Return: %s (%d)\n",*entry_string_p,rc); return rc; free_group_out: if (group) free(group); free_nickname_out: if (nickname) free(nickname); free_ipaddr_out: if (ipaddr) free(ipaddr); free_host_out: if (host) free(host); free_user_out: if (user) free(user); free_buffer_out: if (buffer) free(buffer); return rc;}static inthostlist_userinfo_add_with_answer(const char *message,int *next_count){ int rc; int start,end; char *string; char *sp,*ep; long remains; int intval; size_t len; userdb_t *entry=NULL; size_t this_count; size_t remain_count; int is_last=0; if ( (!message) || (!next_count) ) return -EINVAL; string=strdup(message); if (!string) return -ENOMEM; rc=-ENOENT; len=strlen(message); remains=len; this_count=0; *next_count=0; /* * start */ sp=string; ep=memchr(sp, HOSTLIST_SEPARATOR, remains); if (!ep) goto free_string_out; remains =len - ((unsigned long)ep-(unsigned long)sp); *ep='\0'; start=strtol(sp, (char **)NULL, 10); if (start<0) goto free_string_out; ++ep; dbg_out("Start:%d\n",start); /* * total */ sp=ep; ep=memchr(sp, HOSTLIST_SEPARATOR, remains); if (!ep) goto free_string_out; remains =len - ((unsigned long)ep-(unsigned long)sp); *ep='\0'; end=strtol(sp, (char **)NULL, 10); if (end<0) goto free_string_out; ++ep; dbg_out("End:%d\n",end); if (end<start)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -