⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simple.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <assert.h>#include <string.h>#include <errno.h>#include <glib.h>#include "internal.h"#include "account.h"#include "accountopt.h"#include "debug.h"#include "multi.h"#include "notify.h"#include "prpl.h"#include "request.h"#include "server.h"#include "util.h"#ifdef NO_FORK#include <shlwapi.h>#endif#include "simple.h"static GaimPlugin *my_protocol = NULL;typedef enum{      /* GAIM <-> GAG */      SIMPLE_IM                 = 0x00,      SIMPLE_PRESENCE           = 0x01,      SIMPLE_HELLO              = 0x02,        /* GAIM --> GAG */      SIMPLE_LOGIN              = 0x40,      SIMPLE_LOGOUT             = 0x41,      SIMPLE_ADD_BUDDY          = 0x42,      SIMPLE_REMOVE_BUDDY       = 0x43,      SIMPLE_SHUTDOWN           = 0x44,      /* GAG --> GAIM */      SIMPLE_ERROR              = 0x80,      SIMPLE_LOGIN_STATUS       = 0x81} gag_command_t;/*   In the parent   Read from gag using FD_GAG_TO_GAIM   Write to gag using FD_GAIM_TO_GAG*/#ifdef NO_FORKstatic int gagfd = 0;#define FD_GAG_TO_GAIM gagfd#define FD_GAIM_TO_GAG gagfd#elsestatic int gaimtogag[2];static int gagtogaim[2];#define FD_GAG_TO_GAIM gagtogaim[0]#define FD_GAIM_TO_GAG gaimtogag[1]#endifstatic int gaginitialized = 0;static intisAccountNameUnsafe(char *accountName){   /* There's an open-ended minefield to be explored here.    * This is just a first attempt to keep gaim and gag    * from blowing apart because some user typed in    * "bad stuff (tm)".    */   if (g_strrstr(accountName,"<")!=NULL) {return 1;}   if (g_strrstr(accountName,">")!=NULL) {return 1;}   if (g_strrstr(accountName," ")!=NULL) {return 1;}   if (g_strrstr(accountName,":")!=NULL)   {    if (        ! (    g_str_has_prefix(accountName,"sip:")            || g_str_has_prefix(accountName,"sips:")          )       ) return 1;   }   return 0; }char *buildSIPURI(char *accountName){  if (g_str_has_prefix(accountName,"sip:")) {return g_strdup(accountName);}  if (g_str_has_prefix(accountName,"sips:")) {return g_strdup(accountName);}  return g_strconcat("sip:",accountName,NULL);}static void sippy_get_string( char* buf, int bufSize ){    int len;   int length;      len = read(  FD_GAG_TO_GAIM, &length, sizeof(length) );   assert( len == sizeof(length) );      if ( length+1 >= bufSize )   {      assert(0);   }      if (length)   {     len = read( FD_GAG_TO_GAIM, buf, length );     assert( len == length );   }      buf[length]=0;}static void sippy_get_int( int* i ){    int len;   int length;      len = read(  FD_GAG_TO_GAIM, &length, sizeof(length) );   assert( len == sizeof(length) );      if ( length != sizeof(int) )   {      assert(0);   }      len = read( FD_GAG_TO_GAIM, i, length );   assert( len == length );}static void sippy_get_bool( unsigned char* i ){    int len;   int length;      len = read(  FD_GAG_TO_GAIM, &length, sizeof(length) );   assert( len == sizeof(length) );      if ( length != sizeof(char) )   {      assert(0);   }      len = read( FD_GAG_TO_GAIM, i, length );   assert( len == length );}static void sippy_send_bool( const unsigned char b ){     int len;   int l;   assert( FD_GAIM_TO_GAG );      len=sizeof(b);   l=write( FD_GAIM_TO_GAG, &len, sizeof(len) );   assert( l == sizeof(len) );   l=write( FD_GAIM_TO_GAG, &b, len );   assert( l == len );}static void sippy_send_string( const char* buf ){     int len;   int l;   assert( FD_GAIM_TO_GAG );      /*RjS - Gaim gives us NULLs instead of empty strings sometimes   */         len=(buf==NULL?0:strlen(buf));   l=write( FD_GAIM_TO_GAG, &len, sizeof(len) );   assert( l == sizeof(len) );   if (len>0)   {     l=write( FD_GAIM_TO_GAG, buf, len );     assert( l == len );   }}static void sippy_send_command( const gag_command_t command ){     int l;   assert( FD_GAIM_TO_GAG );   l=write( FD_GAIM_TO_GAG, &command, sizeof(command) );   assert( l == sizeof(command) );}static const char *sippy_list_icon(GaimAccount *a, GaimBuddy *b){	return "sippy";}static voidsippy_recv_cb(gpointer data, gint source, GaimInputCondition condition){  GaimConnection *gc = data;  int len;  int command;  static char buf[4096];  static char bufFrom[4096];  static char bufTo[4096];    len = read( FD_GAG_TO_GAIM, &command, sizeof(command ) );  if ( len == -1 )  {     int err = errno;     gaim_debug(GAIM_DEBUG_INFO,"sippy","err=%d\n",err);       /* something really bad happened */     assert(0);  }  if ( len == 0 )  {     /* not ready */     return;  }  assert( len == sizeof(command) );    switch ( command )  {     case SIMPLE_IM:     {	        gaim_debug(GAIM_DEBUG_INFO,"sippy","got an IM messages from gag\n");          sippy_get_string( bufTo, sizeof(bufTo) );        sippy_get_string( bufFrom, sizeof(bufFrom) );        sippy_get_string( buf, sizeof(buf) );        gaim_debug(GAIM_DEBUG_INFO,"sippy","got an IM from=%s to=%s data=%s\n",bufFrom,bufTo,buf);          serv_got_im(gc,bufFrom,buf,0,time(NULL));      }     break;          case SIMPLE_LOGIN_STATUS:     {        unsigned char success;        int sipCode;                /* bool success, int sipCode, data message */        sippy_get_bool( &success );        sippy_get_int( &sipCode );        sippy_get_string( buf, sizeof(buf) );           gaim_debug(GAIM_DEBUG_INFO,"sippy","got a LOGIN_STATUS status=%d msg=%s\n",sipCode,buf);	if (gaim_connection_get_state(gc) != GAIM_CONNECTED)	{          if (success)          {            gaim_connection_update_progress(gc,_("Connecting"),1,2);            gaim_connection_set_state(gc, GAIM_CONNECTED);          }          else          {            gaim_connection_error(gc, _(buf));          }	}     }     break;          case SIMPLE_PRESENCE: /* uri aor, bool  available, Data status */     {         unsigned char open;	int lastReportedUCStatus;                gaim_debug(GAIM_DEBUG_INFO,"sippy","got a PRES messages from gag\n");        sippy_get_string( bufFrom, sizeof(bufFrom) );        sippy_get_bool( &open );        sippy_get_string( buf, sizeof(buf) );                gaim_debug(GAIM_DEBUG_INFO,"sippy","got a PRES messages from gag from=%s open=%d, msg=%s\n",bufFrom,open,buf);        {	  struct simple_connection_cache *sc_cache = gc->proto_data;	  struct simple_friend_cache *sf;	  	  sf = g_hash_table_lookup(sc_cache->friends,bufFrom);	  if (!sf) {	    sf = simple_friend_cache_new();	    g_hash_table_insert(sc_cache->friends,g_strdup(bufFrom),sf);	  }          if (sf->status_string)	  {	    g_free(sf->status_string);	  } 	  sf->status_string = g_strdup(buf);	  lastReportedUCStatus = (sf->status_int ^= 2);	} 	/* AFAICT, there is a half-done change to the use of	 * the last argument to serv_got_update that is messing	 * up Yahoo as well as us. The code above the prpl abstraction	 * claims the integer is ours to do with as we please, but they	 * use the lowest order bit to mean available or not.	 *	 * Other code looks for changes to this integer - if it has	 * not changed it shortcuts all the GUI updates. So...	 * We're going to game gaim for now by toggling the second	 * lowest order bit each time we call this function.         *         * TODO: This was true in the gaim 0.71 code - need to review to         * see if this is still appropriate.	 */        serv_got_update(gc, bufFrom, (int)open, 0, 0, 0, lastReportedUCStatus);     }     break;          case SIMPLE_HELLO: /* bool ok */     {        unsigned char ok;        sippy_get_bool( &ok );         gaim_debug(GAIM_DEBUG_INFO,"sippy","got a HELLO ok=%d\n",ok);     }          case SIMPLE_ERROR:     {         gaim_debug(GAIM_DEBUG_INFO,"sippy","got an ERROR messages from gag\n");        sippy_get_string( buf, sizeof(buf) );        gaim_debug(GAIM_DEBUG_INFO,"sippy","gag ERROR %s\n",buf);        gaim_request_action(gc, _("SIP Error"), _("SIP Error"), buf,                              0, NULL, 1, _("Okay"), 0);     }     break;          default:        assert(0);  }}static voidsippy_add_buddy(GaimConnection *gc, GaimBuddy *who, GaimGroup *dontCare){   if (!gaginitialized) {return;}   gaim_debug(GAIM_DEBUG_INFO,"sippy","sending ADD BUDDY to gag us=%s them=%s\n",gc->account->username,who->name);   sippy_send_command( SIMPLE_ADD_BUDDY );   sippy_send_string( gc->account->username );   sippy_send_string( who->name );}static voidsippy_logout(GaimConnection *gc){   if (!gaginitialized) {return;}   gaim_debug(GAIM_DEBUG_INFO,"sippy","sending LOGOUT to gag aor=%s\n",gc->account->username);   sippy_send_command( SIMPLE_LOGOUT );   sippy_send_string( gc->account->username );   gaim_debug(GAIM_DEBUG_INFO,"sippy","Removing gag's gaim_input\n");   gaim_input_remove(gc->inpa);}static voidsippy_remove_buddy(GaimConnection *gc, GaimBuddy *who, GaimGroup *group){   if (!gaginitialized) {return;}   gaim_debug(GAIM_DEBUG_INFO,"sippy","sending REMOVE BUDDY to gag us=%s them=%s\n",gc->account->username,who->name);   sippy_send_command( SIMPLE_REMOVE_BUDDY );   sippy_send_string( gc->account->username );   sippy_send_string( who->name );}static gboolean sippy_unload_plugin(GaimPlugin *plugin){    if (gaginitialized)   {     gaim_debug(GAIM_DEBUG_INFO,"sippy","sending SHUTDOWN to gag\n");     sippy_send_command( SIMPLE_SHUTDOWN );   }   return 1;}static voidinit_gag(GaimConnection *gc){  char sanity_check_buffer[8];  int sane;#ifdef NO_FORK  char gag_path[256];  DWORD gag_path_size = 240;#endif  gaim_debug(GAIM_DEBUG_INFO,"sippy","Initializing Gag\n");  #ifdef NO_FORK  {    int listenfd;    int status;    int shell_exec_status;    struct sockaddr_in us;    struct sockaddr_in them;    size_t addr_len = sizeof(them);    char buffer[1024];    memset((void *)&us, 0, sizeof(struct sockaddr_in));    memset((void *)&them, 0, sizeof(struct sockaddr_in));    us.sin_family = AF_INET;    us.sin_port = 0xBEEF;    inet_aton("127.0.0.1", &(us.sin_addr));    listenfd = socket(PF_INET, SOCK_STREAM, 0);    if (listenfd < 0)    {      /* We're single threaded, so strerror is safe */      snprintf(buffer, sizeof(buffer),                "Unable to start the SIP engine - "               "Could not create loopback socket; err = %d (%s)",               errno, strerror(errno));      gaim_connection_error(gc, buffer);      return;    }    status = bind (listenfd, (struct sockaddr*)&us, sizeof(struct sockaddr));    if (status != 0)    {      /* We're single threaded, so strerror is safe */      snprintf(buffer, sizeof(buffer),                "Unable to start the SIP engine - "               "Could not bind to loopback socket; err = %d (%s)",               errno, strerror(errno));      gaim_connection_error(gc, buffer);      return;    }     status = listen(listenfd, 1);    if (status != 0)    {      /* We're single threaded, so strerror is safe */      snprintf(buffer, sizeof(buffer),                "Unable to start the SIP engine - "               "Could not listen on loopback socket; err = %d (%s)",               errno, strerror(errno));      gaim_connection_error(gc, buffer);      return;    }    /* Start SIP engine */    /* First, check in the directory into which Gaim is installed */    SHRegGetUSValue ("SOFTWARE\\gaim", NULL, NULL,                      (LPVOID)gag_path,                      &gag_path_size,                      TRUE,                     NULL, 0);    strcat(gag_path, "\\gag.exe");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -