📄 gnunet-chat.c
字号:
/* This file is part of GNUnet. (C) 2007, 2008 Christian Grothoff (and other contributing authors) GNUnet 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, or (at your option) any later version. GNUnet 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 GNUnet; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//** * @file applications/chat/tools/gnunet-chat.c * @brief Minimal chat command line tool * @author Christian Grothoff * @author Nathan Evans */#include "platform.h"#include "gnunet_protocols.h"#include "gnunet_directories.h"#include "gnunet_chat_lib.h"#define MAX_MESSAGE_LENGTH (32 * 1024)static struct GNUNET_GC_Configuration *cfg;static struct GNUNET_GE_Context *ectx;static char *cfgFilename = GNUNET_DEFAULT_CLIENT_CONFIG_FILE;static char *nickname;static char *room_name;static struct GNUNET_Mutex *lock;static struct GNUNET_CHAT_Room *room;static struct GNUNET_MetaData *meta;struct UserList{ struct UserList *next; GNUNET_RSA_PublicKey pkey; int ignored;};static struct UserList *users;struct ChatCommand{ const char *command; int (*Action) (const char *arguments, const void *xtra); const char *helptext;};static voidfree_user_list (){ struct UserList *next; while (users != NULL) { next = users->next; GNUNET_free (users); users = next; }}/** * A message was sent in the chat to us. * * @param timestamp when was the message sent? * @param senderNick what is the nickname of the sender? (maybe NULL) * @param message the message (maybe NULL, especially if confirmation * is requested before delivery; the protocol will ensure * that this function is called again with the full message * if a confirmation is transmitted; if the message is NULL, * the user is merely asked if engaging in the exchange is ok * @param room in which room was the message received? * @param options options for the message * @return GNUNET_OK to accept the message now, GNUNET_NO to * accept (but user is away), GNUNET_SYSERR to signal denied delivery */static intreceive_callback (void *cls, struct GNUNET_CHAT_Room *room, const GNUNET_HashCode * sender, const struct GNUNET_MetaData *meta, const char *message, GNUNET_CHAT_MSG_OPTIONS options){ char *nick; const char *fmt; if (sender != NULL) nick = GNUNET_pseudonym_id_to_name (ectx, cfg, sender); else nick = GNUNET_strdup (_("anonymous")); fmt = NULL; switch (options) { case GNUNET_CHAT_MSG_OPTION_NONE: case GNUNET_CHAT_MSG_ANONYMOUS: fmt = _("`%s' said: %s\n"); break; case GNUNET_CHAT_MSG_PRIVATE: fmt = _("`%s' said to you: %s\n"); break; case GNUNET_CHAT_MSG_PRIVATE | GNUNET_CHAT_MSG_ANONYMOUS: fmt = _("`%s' said to you: %s\n"); break; case GNUNET_CHAT_MSG_AUTHENTICATED: fmt = _("`%s' said for sure: %s\n"); break; case GNUNET_CHAT_MSG_PRIVATE | GNUNET_CHAT_MSG_AUTHENTICATED: fmt = _("`%s' said to you for sure: %s\n"); break; case GNUNET_CHAT_MSG_ACKNOWLEDGED: fmt = _("`%s' was confirmed that you received: %s\n"); break; case GNUNET_CHAT_MSG_PRIVATE | GNUNET_CHAT_MSG_ACKNOWLEDGED: fmt = _("`%s' was confirmed that you and only you received: %s\n"); break; case GNUNET_CHAT_MSG_AUTHENTICATED | GNUNET_CHAT_MSG_ACKNOWLEDGED: fmt = _("`%s' was confirmed that you received from him or her: %s\n"); break; case GNUNET_CHAT_MSG_AUTHENTICATED | GNUNET_CHAT_MSG_PRIVATE | GNUNET_CHAT_MSG_ACKNOWLEDGED: fmt = _ ("`%s' was confirmed that you and only you received from him or her: %s\n"); break; case GNUNET_CHAT_MSG_OFF_THE_RECORD: fmt = _("`%s' said off the record: %s\n"); break; default: fmt = _("<%s> said using an unknown message type: %s\n"); break; } fprintf (stdout, fmt, nick, message); GNUNET_free (nick); return GNUNET_OK;}static intmember_list_callback (void *cls, const struct GNUNET_MetaData *member_info, const GNUNET_RSA_PublicKey * member_id, GNUNET_CHAT_MSG_OPTIONS options){ char *nick; GNUNET_HashCode id; struct UserList *pos; struct UserList *prev; GNUNET_hash (member_id, sizeof (GNUNET_RSA_PublicKey), &id); nick = GNUNET_pseudonym_id_to_name (ectx, cfg, &id); fprintf (stdout, member_info != NULL ? _("`%s' entered the room\n") : _("`%s' left the room\n"), nick); GNUNET_free (nick); GNUNET_mutex_lock (lock); if (member_info != NULL) { /* user joining */ pos = GNUNET_malloc (sizeof (struct UserList)); pos->next = users; pos->pkey = *member_id; pos->ignored = GNUNET_NO; users = pos; } else { /* user leaving */ prev = NULL; pos = users; while ((pos != NULL) && (0 != memcmp (&pos->pkey, member_id, sizeof (GNUNET_RSA_PublicKey)))) { prev = pos; pos = pos->next; } if (pos == NULL) { GNUNET_GE_BREAK (NULL, 0); } else { if (prev == NULL) users = pos->next; else prev->next = pos->next; GNUNET_free (pos); } } GNUNET_mutex_unlock (lock); return GNUNET_OK;}/** * Message delivery confirmations. * * @param timestamp when was the message received? * @param message the message (maybe NULL) * @param room in which room was the message received? * @param receipt signature confirming delivery (maybe NULL, only * if confirmation was requested) * @return GNUNET_OK to continue, GNUNET_SYSERR to refuse processing further * confirmations from anyone for this message */static intconfirmation_callback (void *cls, struct GNUNET_CHAT_Room *room, unsigned int orig_seq_number, GNUNET_CronTime timestamp, const GNUNET_HashCode * receiver, const GNUNET_HashCode * msg_hash, const GNUNET_RSA_Signature * receipt){ return GNUNET_OK;}static intdo_transmit (const char *msg, const void *xtra){ unsigned int seq; if (GNUNET_OK != GNUNET_CHAT_send_message (room, msg, GNUNET_CHAT_MSG_OPTION_NONE, NULL, &seq)) fprintf (stderr, _("Failed to send message.\n")); return GNUNET_OK;}static intdo_join (const char *arg, const void *xtra){ char *my_name; GNUNET_HashCode me; if (arg[0] == '#') arg++; /* ignore first hash */ GNUNET_CHAT_leave_room (room); free_user_list (); GNUNET_free (room_name); room_name = GNUNET_strdup (arg); room = GNUNET_CHAT_join_room (ectx, cfg, nickname, meta, room_name, -1, &receive_callback, NULL, &member_list_callback, NULL, &confirmation_callback, NULL, &me); my_name = GNUNET_pseudonym_id_to_name (ectx, cfg, &me); fprintf (stdout, _("Joined room `%s' as user `%s'.\n"), room_name, my_name); GNUNET_free (my_name); return GNUNET_OK;}static intdo_nick (const char *msg, const void *xtra){ char *my_name; GNUNET_HashCode me; GNUNET_CHAT_leave_room (room); free_user_list (); GNUNET_free (nickname); GNUNET_meta_data_destroy (meta);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -