/* 'File Association Manager'-Plugin for Miranda IM Copyright (C) 2005-2007 H. Herkenrath This program 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. This program 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 (AssocMgr-License.txt); if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // -- Includes #include "stdafx.h" /* #define AIM_SUPPORT_TEST #define ICQ_SUPPORT_TEST #define YAHOO_SUPPORT_TEST #define MSN_SUPPORT_TEST #define GG_SUPPORT_TEST #define JABBER_SUPPORT_TEST */ // ----------------------------------------- extern HINSTANCE hInst; /* a copy of those in m_assocmgr.h, as we did not #include those helpers */ __inline static int AssocMgr_AddNewFileTypeT(const char *ext,const char *mime,const TCHAR *desc,const TCHAR *verb,HINSTANCE hinst,UINT iconid,const char *service,DWORD flags) { FILETYPEDESC ftd; ftd.cbSize=sizeof(FILETYPEDESC); ftd.pszFileExt=ext; ftd.pszMimeType=mime; ftd.ptszDescription=desc; ftd.hInstance=hinst; ftd.nIconResID=iconid; ftd.ptszVerbDesc=verb; ftd.pszService=service; ftd.flags=flags|FTDF_TCHAR; return CallService(MS_ASSOCMGR_ADDNEWFILETYPE,0,(LPARAM)&ftd); } static int __inline AssocMgr_AddNewUrlType(const char *prefix,const char *desc,HINSTANCE hinst,UINT iconid,const char *service,DWORD flags) { URLTYPEDESC utd; utd.cbSize=sizeof(URLTYPEDESC); utd.pszProtoPrefix=prefix; utd.pszDescription=desc; utd.hInstance=hinst; utd.nIconResID=iconid; utd.pszService=service; utd.flags=flags&~UTDF_UNICODE; return CallService(MS_ASSOCMGR_ADDNEWURLTYPE,0,(LPARAM)&utd); } // ----------------------------------------- #ifdef AIM_SUPPORT_TEST #define AIM_PROTOCOL_NAME "AIM" #define IDI_AOL 28 #define MOD_KEY_CL "CList" #define AIM_KEY_NL "NotOnList" struct oscar_data { HINSTANCE hInstance; } static conn; static __inline HANDLE find_contact(const char *nick) { nick; return NULL; } static __inline HANDLE add_contact(const char *nick) { nick; return db_find_first(); } static __inline void aim_gchat_joinrequest(const char *room, int exchange) { room; exchange; MessageBoxA(NULL,"Join group chat!",room,MB_OK); return; } #include #include #include "m_assocmgr.h" static HANDLE hHookModulesLoaded; static HANDLE hServiceParseLink; static int ServiceParseAimLink(WPARAM,LPARAM lParam) { char *arg=(char*)lParam; if(arg==NULL) return 1; /* sanity check */ /* skip leading prefix */ arg=strchr(arg,':'); if(arg==NULL) return 1; /* parse failed */ for (++arg;*arg=='/';++arg); /* add user: aim:addbuddy?screenname=NICK&groupname=GROUP send message: aim:goim?screenname=NICK&message=MSG open chatroom: aim:gochat?roomname=ROOM&exchange=NUM */ /* add a contact to the list */ if (!_strnicmp(arg,"addbuddy?",9)) { char *tok,*sn=NULL,*group=NULL; ADDCONTACTSTRUCT acs; PROTOSEARCHRESULT psr; if (*(arg+=9)==0) return 1; /* parse failed */ tok=strtok(arg,"&"); /* first token */ while(tok!=NULL) { if (!_strnicmp(tok,"screenname=",11) && *(tok+11)!=0) sn=Netlib_UrlDecode(tok+11); if (!_strnicmp(tok,"groupname=",10) && *(tok+10)!=0) group=Netlib_UrlDecode(tok+10); /* group is currently ignored */ tok=strtok(NULL,"&"); /* next token */ } if(sn==NULL) return 1; /* parse failed */ if(find_contact(sn)==NULL) { /* does not yet check if sn is current user */ acs.handleType=HANDLE_SEARCHRESULT; acs.szProto=AIM_PROTOCOL_NAME; acs.psr=&psr; memset(&psr, 0, sizeof(PROTOSEARCHRESULT)); psr.cbSize=sizeof(PROTOSEARCHRESULT); psr.nick.t=sn; CallService(MS_ADDCONTACT_SHOW,0,(LPARAM)&acs); } return 0; } /* send a message to a contact */ else if (!_strnicmp(arg,"goim?",5)) { char *tok,*sn=NULL,*msg=NULL; MCONTACT hContact; if (*(arg+=5)==0) return 1; /* parse failed */ tok=strtok(arg,"&"); /* first token */ while(tok!=NULL) { if (!_strnicmp(tok,"screenname=",11) && *(tok+11)!=0) sn=Netlib_UrlDecode(tok+11); if (!_strnicmp(tok,"message=",8) && *(tok+8)!=0) msg=Netlib_UrlDecode(tok+8); tok=strtok(NULL,"&"); /* next token */ } if(sn==NULL) return 1; /* parse failed */ if(ServiceExists(MS_MSG_SENDMESSAGE)) { hContact=find_contact(sn); if(hContact==NULL) { hContact=add_contact(sn); /* does not yet check if sn is current user */ if(hContact!=NULL) db_set_b(hContact,MOD_KEY_CL,AIM_KEY_NL,1); } if(hContact!=NULL) CallService(MS_MSG_SENDMESSAGE,hContact,(LPARAM)msg); } return 0; } /* open a chatroom */ else if (!_strnicmp(arg,"gochat?",7)) { char *tok,*rm=NULL; int exchange=0; if (*(arg+=7)==0) return 1; /* parse failed */ tok=strtok(arg,"&"); /* first token */ while(tok!=NULL) { if (!_strnicmp(tok,"roomname=",9) && *(tok+9)!=0) rm=Netlib_UrlDecode(tok+9); if (!_strnicmp(tok,"exchange=",9)) exchange=atoi(Netlib_UrlDecode(tok+9)); tok=strtok(NULL,"&"); /* next token */ } if(rm==NULL || exchange<=0) return 1; /* parse failed */ aim_gchat_joinrequest(rm,exchange); return 0; } return 1; /* parse failed */ } static int AimLinksModulesLoaded(WPARAM wParam,LPARAM lParam) { char service_name[MAXMODULELABELLENGTH]; UNREFERENCED_PARAMETER(wParam); UNREFERENCED_PARAMETER(lParam); mir_snprintf(service_name,SIZEOF(service_name),"%s%s",AIM_PROTOCOL_NAME,"ParseAimLink"); /* or "AOL Instant Messenger Links" */ AssocMgr_AddNewUrlType("aim:",Translate("AIM link protocol"),conn.hInstance,IDI_AOL,service_name,0); return 0; } void aim_links_init() { char service_name[MAXMODULELABELLENGTH]; //LOG(LOG_DEBUG,"Links: init"); mir_snprintf(service_name,SIZEOF(service_name),"%s%s",AIM_PROTOCOL_NAME,"ParseAimLink"); hServiceParseLink=CreateServiceFunction(service_name,ServiceParseAimLink); hHookModulesLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,AimLinksModulesLoaded); } void aim_links_destroy() { //LOG(LOG_DEBUG,"Links: destroy"); UnhookEvent(hHookModulesLoaded); DestroyServiceFunction(hServiceParseLink); } #endif // ----------------------------------------- #ifdef ICQ_SUPPORT_TEST #define gpszICQProtoName "ICQ" #define IDI_ICQ 101 #define hInst GetModuleHandleA("ICQ") static __inline HANDLE HContactFromUIN(DWORD dwUIN,int *Added) { dwUIN; Added; return db_find_first(); } static __inline HANDLE ICQFindFirstContact(void) { return NULL; } static __inline HANDLE ICQFindNextContact(MCONTACT hContact) { hContact; return NULL; } static __inline void AddToCache(MCONTACT hContact,DWORD dwUin) { hContact; dwUin; } static __inline DWORD ICQGetContactSettingUIN(MCONTACT hContact) { hContact; return 0; } static __inline HANDLE HandleFromCacheByUin(DWORD dwUin) { dwUin; return NULL; } #include #include typedef struct { PROTOSEARCHRESULT hdr; DWORD uin; BYTE auth; char* uid; } ICQSEARCHRESULT; #include "m_assocmgr.h" static HANDLE hHookModulesLoaded; static HANDLE hServiceOpenFile; static void TrimString(char *str) { int len,start; len=mir_strlen(str); while(str[0]!='\0' && (unsigned char)str[len-1]<=' ') str[--len]=0; for(start=0;str[start] && (unsigned char)str[start]<=' ';++start); memmove(str,str+start,len-start+1); } static BOOL IsEmpty(const char *str) { int i; for(i=0;str[i]!='\0';i++) if(str[i]!=' ' && str[i]!='\r' && str[i]!='\n') return FALSE; return TRUE; } #define ICQFILE_MESSAGEUSER 1 #define ICQFILE_ADDUSER 2 typedef struct { int type; char uin[64]; char email[128]; char nick[128]; char firstName[64]; char lastName[64]; } ICQFILEINFO; static HANDLE IsHContactFromUIN(DWORD uin) { MCONTACT hContact; DWORD dwUin; hContact=HandleFromCacheByUin(uin); if(hContact!=NULL) return hContact; hContact=ICQFindFirstContact(); while(hContact!=NULL) { dwUin=ICQGetContactSettingUIN(hContact); if(dwUin==uin) { AddToCache(hContact,dwUin); return hContact; } hContact=ICQFindNextContact(hContact); } return NULL; } static void AddIcqUser(ICQFILEINFO *info) { ADDCONTACTSTRUCT acs; ICQSEARCHRESULT psr; DWORD uin; /* check that uin does not belong to current user */ uin=atoi(info->uin); if(uin!=0 && uin!=ICQGetContactSettingUIN(NULL)) { /* not yet present? */ if(IsHContactFromUIN(uin)==NULL) { acs.handleType=HANDLE_SEARCHRESULT; acs.szProto=gpszICQProtoName; acs.psr=(PROTOSEARCHRESULT*)&psr; memset(&psr, 0, sizeof(ICQSEARCHRESULT)); psr.hdr.cbSize=sizeof(ICQSEARCHRESULT); if(info->nick[0]) psr.hdr.nick=info->nick; else psr.hdr.nick=info->uin; if(info->email[0]) psr.hdr.email=info->email; if(info->firstName[0]) psr.hdr.firstName=info->firstName; if(info->lastName[0]) psr.hdr.lastName=info->lastName; psr.uin=uin; psr.auth=1; /* authentication needed flag */ psr.uid=NULL; /* icq contact */ CallService(MS_ADDCONTACT_SHOW,0,(LPARAM)&acs); } } } static void MessageIcqUser(ICQFILEINFO *info) { MCONTACT hContact; if(ServiceExists(MS_MSG_SENDMESSAGE)) { hContact=HContactFromUIN(atoi(info->uin),NULL); /* adds the contact if needed */ if(hContact!=NULL) CallService(MS_MSG_SENDMESSAGE,hContact,0); } } static int IcqOpenFile(WPARAM wParam,LPARAM lParam) { TCHAR *pszFile=(TCHAR*)lParam; /* TCHAR is specified on AssocMgr_AddNewFileTypeT() */ FILE *fp; ICQFILEINFO info; char line[4096],*sep; UNREFERENCED_PARAMETER(wParam); /* send message: [ICQ Message User] UIN=1234567 add user: (all the .uin files I've seen only have UIN= in them) [ICQ User] UIN=1234567 Email= NickName= FirstName= LastName= */ if(pszFile==NULL) return 1; /* sanity check */ fp=_tfopen(pszFile,_T("rt")); if(fp==NULL) return 1; /* open failed */ info.type=0; while(!feof(fp)) { if(fgets(line,sizeof(line),fp)==NULL) break; TrimString(line); if(IsEmpty(line)) continue; if(line[0]=='[') { memset(&info, 0, sizeof(info)); if (!mir_strcmpi(line,"[ICQ Message User]")) info.type=ICQFILE_MESSAGEUSER; else if (!mir_strcmpi(line,"[ICQ User]")) info.type=ICQFILE_ADDUSER; continue; } if(info.type==0) continue; sep=strchr(line,'='); if(sep==NULL) { info.type=0; break; } /* format error */ *(sep++)='\0'; if (!mir_strcmp("UIN",line)) mir_strncpy(info.uin,sep,sizeof(info.uin)); /* buffer safe */ else if (!mir_strcmp("Email",line)) mir_strncpy(info.email,sep,sizeof(info.email)); /* buffer safe */ else if (!mir_strcmp("NickName",line)) mir_strncpy(info.nick,sep,sizeof(info.nick)); /* buffer safe */ else if (!mir_strcmp("FirstName",line)) mir_strncpy(info.firstName,sep,sizeof(info.firstName)); /* buffer safe */ else if (!mir_strcmp("LastName",line)) mir_strncpy(info.lastName,sep,sizeof(info.lastName)); /* buffer safe */ } fclose(fp); switch(info.type) { case ICQFILE_MESSAGEUSER: MessageIcqUser(&info); return 0; case ICQFILE_ADDUSER: AddIcqUser(&info); return 0; default: return 1; /* open failed */ } } static int IcqFilesModulesLoaded(WPARAM wParam,LPARAM lParam) { char szService[MAX_PATH+32]; UNREFERENCED_PARAMETER(wParam); UNREFERENCED_PARAMETER(lParam); mir_strcat(mir_strcpy(szService,gpszICQProtoName),"OpenFile"); /* .icq files are not used, just by the ProtoLink plugin */ //AssocMgr_AddNewFileTypeT(".icq","application/x-icq",TranslateT("ICQ link shortcut"),TranslateT("&Add to contact list..."),hInst,IDI_ICQ,szService,FTDF_BROWSERAUTOOPEN|FTDF_ISTEXT|FTDF_ISSHORTCUT|FTDF_DEFAULTDISABLED); AssocMgr_AddNewFileTypeT(".uin","application/x-icq",TranslateT("ICQ link shortcut"),TranslateT("&Add to contact list..."),hInst,IDI_ICQ,szService,FTDF_BROWSERAUTOOPEN|FTDF_ISTEXT|FTDF_ISSHORTCUT); return 0; } void InitIcqFiles(void) { char szService[MAX_PATH+32]; mir_strcat(mir_strcpy(szService,gpszICQProtoName),"OpenFile"); hServiceOpenFile=CreateServiceFunction(szService,IcqOpenFile); hHookModulesLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,IcqFilesModulesLoaded); } void UninitIcqFiles(void) { UnhookEvent(hHookModulesLoaded); DestroyServiceFunction(hServiceOpenFile); } #undef hInst #endif // ----------------------------------------- #ifdef YAHOO_SUPPORT_TEST #define yahooProtocolName "YAHOO" #define IDI_YAHOO 10101 #define hinstance GetModuleHandleA("YAHOO") static __inline HANDLE getbuddyH(const char *yahoo_id) { yahoo_id; return NULL; } static __inline HANDLE add_buddy(const char *yahoo_id,const char *yahoo_name,DWORD flags) { yahoo_id; yahoo_name; flags; return db_find_first(); } #include #include #include "m_assocmgr.h" static HANDLE hHookModulesLoaded; static HANDLE hServiceParseYmsgrLink; static int ServiceParseYmsgrLink(WPARAM wParam,LPARAM lParam) { char *arg=(char*)lParam; UNREFERENCED_PARAMETER(wParam); if(arg==NULL) return 1; /* sanity check */ /* add user: ymsgr:addfriend?ID send message: ymsgr:sendim?ID&m=MESSAGE add chatroom: ymsgr:chat?ROOM */ /* skip leading prefix */ arg=strchr(arg,':'); if(arg==NULL) return 1; /* parse failed */ for (++arg;*arg=='/';++arg); /* add a contact to the list */ if (!_strnicmp(arg,"addfriend?",10)) { char *tok,*id=NULL; ADDCONTACTSTRUCT acs; PROTOSEARCHRESULT psr; if (*(arg+=10)==0) return 1; /* parse failed */ tok=strtok(arg,"&"); /* first token */ if(tok!=NULL) id=Netlib_UrlDecode(tok); if(id==NULL || *id==0) return 1; /* parse failed */ if(getbuddyH(id)==NULL) { /* does not yet check if id is current user */ acs.handleType=HANDLE_SEARCHRESULT; acs.szProto=yahooProtocolName; acs.psr=&psr; memset(&psr, 0, sizeof(PROTOSEARCHRESULT)); psr.cbSize=sizeof(PROTOSEARCHRESULT); psr.nick.t=id; CallService(MS_ADDCONTACT_SHOW,0,(LPARAM)&acs); } return 0; } /* send a message to a contact */ else if (!_strnicmp(arg,"sendim?",7)) { char *tok,*id=NULL,*msg=NULL; MCONTACT hContact; if (*(arg+=7)==0) return 1; /* parse failed */ tok=strtok(arg,"&"); /* first token */ if(tok!=NULL) id=tok; while(tok!=NULL) { if (!_strnicmp(tok,"m=",2) && *(tok+2)!=0) msg=Netlib_UrlDecode(tok+2); tok=strtok(NULL,"&"); /* next token */ } if(id==NULL || *id==0) return 1; /* parse failed */ if(ServiceExists(MS_MSG_SENDMESSAGE)) { /* does not yet check if sn is current user */ hContact=add_buddy(id,id,PALF_TEMPORARY); /* ensure contact is on list */ if(hContact!=NULL) CallService(MS_MSG_SENDMESSAGE,hContact,(LPARAM)msg); } return 0; } /* open a chatroom */ else if (!_strnicmp(arg,"chat?",5)) { char *tok,*rm=NULL; if (*(arg+=5)==0) return 1; /* parse failed */ tok=strtok(arg,"&"); /* first token */ if(tok!=NULL) rm=Netlib_UrlDecode(tok); if(rm==NULL) return 1; /* parse failed */ /* not yet implemented (rm contains name of chatroom)*/ return 0; } return 1; /* parse failed */ } static int YmsgrLinksModulesLoaded(WPARAM wParam,LPARAM lParam) { char szService[MAXMODULELABELLENGTH]; UNREFERENCED_PARAMETER(wParam); UNREFERENCED_PARAMETER(lParam); mir_snprintf(szService,SIZEOF(szService),"%s%s",yahooProtocolName,"ParseYmsgrLink"); AssocMgr_AddNewUrlType("ymsgr:",Translate("Yahoo link protocol"),hinstance,IDI_YAHOO,szService,0); return 0; } void YmsgrLinksInit(void) { char szService[MAXMODULELABELLENGTH]; mir_snprintf(szService,SIZEOF(szService),"%s%s",yahooProtocolName,"ParseYmsgrLink"); hServiceParseYmsgrLink=CreateServiceFunction(szService,ServiceParseYmsgrLink); hHookModulesLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,YmsgrLinksModulesLoaded); } void YmsgrLinksUninit(void) { UnhookEvent(hHookModulesLoaded); DestroyServiceFunction(hServiceParseYmsgrLink); } #undef hinstance #endif // ----------------------------------------- #ifdef MSN_SUPPORT_TEST #define msnProtocolName "MSN" #define IDI_MSN 101 #define hInst GetModuleHandleA("MSN") static __inline HANDLE MSN_HContactFromEmailT(const char *msnEmail) { msnEmail; return NULL; } static __inline HANDLE MSN_HContactFromEmail(const char *msnEmail,const char *msnNick,int addIfNeeded,int temporary) { msnEmail; msnNick; addIfNeeded; temporary; return db_find_first(); } #include #include #include "m_assocmgr.h" static HANDLE hHookModulesLoaded; static HANDLE hServiceParseMsnimLink; static int ServiceParseMsnimLink(WPARAM wParam,LPARAM lParam) { char *arg=(char*)lParam; UNREFERENCED_PARAMETER(wParam); if(arg==NULL) return 1; /* sanity check */ /* add user: msnim:add?contact=netpassport@emailaddress.com send message: msnim:chat?contact=netpassport@emailaddress.com voice chat: msnim:voice?contact=netpassport@emailaddress.com video chat: msnim:video?contact=netpassport@emailaddress.com */ /* skip leading prefix */ arg=strchr(arg,':'); if(arg==NULL) return 1; /* parse failed */ for (++arg;*arg=='/';++arg); /* add a contact to the list */ if (!_strnicmp(arg,"add?",4)) { char *tok,*email=NULL; ADDCONTACTSTRUCT acs; PROTOSEARCHRESULT psr; if (*(arg+=4)==0) return 1; /* parse failed */ tok=strtok(arg,"&"); /* first token */ while(tok!=NULL) { if (!_strnicmp(tok,"contact=",8) && *(tok+11)!=0) email=Netlib_UrlDecode(tok+11); tok=strtok(NULL,"&"); /* next token */ } if(email==NULL || *email==0) return 1; /* parse failed */ if(MSN_HContactFromEmailT(email)==NULL) { /* does not yet check if email is current user */ acs.handleType=HANDLE_SEARCHRESULT; acs.szProto=AIM_PROTOCOL_NAME; acs.psr=&psr; memset(&psr, 0, sizeof(PROTOSEARCHRESULT)); psr.cbSize=sizeof(PROTOSEARCHRESULT); psr.nick.t=email; psr.email.t=email; CallService(MS_ADDCONTACT_SHOW,0,(LPARAM)&acs); } return 0; } /* send a message to a contact */ /* "voice" and "video" not yet implemented, perform same action as "chat" */ else if (!_strnicmp(arg,"chat?",5) || !_strnicmp(arg,"voice?",6) || !_strnicmp(arg,"video?",6)) { char *tok,*email=NULL; MCONTACT hContact; if (*(arg+=5)==0) return 1; /* parse failed */ if (*arg=='?' && *(++arg)==0) return 1; /* for "voice?" and "video?" */ tok=strtok(arg,"&"); /* first token */ while(tok!=NULL) { if (!_strnicmp(tok,"contact=",8) && *(tok+11)!=0) email=Netlib_UrlDecode(tok+11); tok=strtok(NULL,"&"); /* next token */ } if(email==NULL || *email==0) return 1; /* parse failed */ if(ServiceExists(MS_MSG_SENDMESSAGE)) { hContact=MSN_HContactFromEmail(email,email,TRUE,TRUE); /* does not yet check if email is current user */ if(hContact!=NULL) CallService(MS_MSG_SENDMESSAGE,hContact,0); } return 0; } return 1; /* parse failed */ } static int MsnLinksModulesLoaded(WPARAM wParam,LPARAM lParam) { char szService[MAXMODULELABELLENGTH]; UNREFERENCED_PARAMETER(wParam); UNREFERENCED_PARAMETER(lParam); mir_snprintf(szService,SIZEOF(szService),"%s%s",msnProtocolName,"ParseMsnimLink"); AssocMgr_AddNewUrlType("msnim:",Translate("MSN link protocol"),hInst,IDI_MSN,szService,0); return 0; } int LoadMsnLinks(void) { char szService[MAXMODULELABELLENGTH]; mir_snprintf(szService,SIZEOF(szService),"%s%s",msnProtocolName,"ParseMsnimLink"); hServiceParseMsnimLink=CreateServiceFunction(szService,ServiceParseMsnimLink); hHookModulesLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,MsnLinksModulesLoaded); return 0; } void UnloadMsnLinks(void) { UnhookEvent(hHookModulesLoaded); DestroyServiceFunction(hServiceParseMsnimLink); } #undef hInst #endif // ----------------------------------------- #ifdef GG_SUPPORT_TEST #define GG_PROTO "GG" #define IDI_GG 251 #define hInstance GetModuleHandleA("GG") typedef DWORD uin_t; static __inline HANDLE gg_getcontact(uin_t uin,int create,int inlist,char *szNick) { uin; create; inlist; szNick; return db_find_first(); } #include #include #include "m_assocmgr.h" static HANDLE hHookModulesLoaded; static HANDLE hServiceParseLink; static int ServiceParseLink(WPARAM wParam,LPARAM lParam) { char *arg=(char*)lParam; UNREFERENCED_PARAMETER(wParam); if(arg==NULL) return 1; /* sanity check */ /* send message: gg:UID */ /* skip leading prefix */ arg=strchr(arg,':'); if(arg==NULL) return 1; /* parse failed */ for (++arg;*arg=='/';++arg); /* send a message to a contact */ { MCONTACT hContact; if(ServiceExists(MS_MSG_SENDMESSAGE)) { hContact=gg_getcontact(atoi(arg),TRUE,FALSE,arg); if(hContact!=NULL) CallService(MS_MSG_SENDMESSAGE,hContact,0); } } return 0; } static int LinksModulesLoaded(WPARAM wParam,LPARAM lParam) { char szService[MAXMODULELABELLENGTH]; UNREFERENCED_PARAMETER(wParam); UNREFERENCED_PARAMETER(lParam); mir_snprintf(szService,SIZEOF(szService),"%s%s",GG_PROTO,"ParseMsnimLink"); AssocMgr_AddNewUrlType("gg:",Translate("Gadu-Gadu link protocol"),hInstance,IDI_GG,szService,0); return 0; } void gg_registerlinks(void) { char szService[MAXMODULELABELLENGTH]; mir_snprintf(szService,SIZEOF(szService),"%s%s",GG_PROTO,"ParseLink"); hServiceParseLink=CreateServiceFunction(szService,ServiceParseLink); hHookModulesLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,LinksModulesLoaded); } void gg_unregisterlinks(void) { UnhookEvent(hHookModulesLoaded); DestroyServiceFunction(hServiceParseLink); } #undef hInstance #endif // ----------------------------------------- #ifdef JABBER_SUPPORT_TEST #define jabberProtoName "JABBER" #define IDI_JABBER 102 #define hInst GetModuleHandleA("JABBER") static __inline HANDLE JabberHContactFromJID(const char *jid) { jid; return NULL; } static __inline HANDLE JabberDBCreateContact(char *jid,char *nick,BOOL temporary,BOOL stripResource) { jid; nick; temporary; stripResource; return db_find_first(); } #include #include #include "m_assocmgr.h" static HANDLE hHookModulesLoaded; static HANDLE hServiceParseXmppURI; static int ServiceParseXmppURI(WPARAM wParam,LPARAM lParam) { char *arg=(char*)lParam; char *jid; UNREFERENCED_PARAMETER(wParam); if(arg==NULL) return 1; /* sanity check */ /* skip leading prefix */ arg=strchr(arg,':'); if(arg==NULL) return 1; /* parse failed */ for (++arg;*arg=='/';++arg); /* complete specification: http://www.xmpp.org/extensions/xep-0147.html send message: xmpp:JID?message;subject=TEXT&body=TEXT add user: xmpp:JID?roster remove user: xmpp:JID?remove */ /* user id */ arg=strchr(jid=arg,'?'); if(arg==NULL) arg+=mir_strlen(arg); /* points to terminating nul */ else *(arg++)=0; if (*jid==0) return 1; /* parse failed */ /* send a message to a contact */ else if (*arg==0 || (!_strnicmp(arg,"message",7) && (*(arg+7)==';' || *(arg+7)==0))) { char *tok,*subj=NULL,*body=NULL; MCONTACT hContact; char msg[1024]; arg+=7; while(*arg==';') ++arg; tok=strtok(arg,"&"); /* first token */ while(tok!=NULL) { if (!_strnicmp(tok,"subject=",8) && *(tok+8)!=0) subj=Netlib_UrlDecode(tok+8); if (!_strnicmp(tok,"body=",5) && *(tok+5)!=0) body=Netlib_UrlDecode(tok+5); tok=strtok(NULL,"&"); /* next token */ } if(ServiceExists(MS_MSG_SENDMESSAGE)) { hContact=JabberDBCreateContact(jid,jid,TRUE,FALSE); if(subj!=NULL && body!=NULL) { mir_snprintf(msg,SIZEOF(msg),"%.128s %s",subj,body); body=msg; } else if(body==NULL) body=subj; if(hContact!=NULL) CallService(MS_MSG_SENDMESSAGE,hContact,(LPARAM)body); } return 0; } /* add user to contact list */ else if (!_strnicmp(arg,"roster",6) && (*(arg+6)==';' || *(arg+6)==0)) { ADDCONTACTSTRUCT acs; PROTOSEARCHRESULT psr; if(JabberHContactFromJID(jid)==NULL) { /* does not yet check if jid belongs to current user */ acs.handleType=HANDLE_SEARCHRESULT; acs.szProto=jabberProtoName; acs.psr=&psr; memset(&psr, 0, sizeof(PROTOSEARCHRESULT)); psr.cbSize=sizeof(PROTOSEARCHRESULT); psr.nick.t=jid; CallService(MS_ADDCONTACT_SHOW,0,(LPARAM)&acs); } return 0; } /* remove user from contact list */ else if (!_strnicmp(arg,"remove",6) && (*(arg+6)==';' || *(arg+6)==0)) { MCONTACT hContact; hContact=JabberHContactFromJID(jid); if(hContact==NULL) /* not yet implemented: show standard miranda dialog here */ CallService(MS_DB_CONTACT_DELETE,hContact,0); return 0; } /* add user subscription */ else if (!_strnicmp(arg,"subscribe",9) && (*(arg+9)==';' || *(arg+9)==0)) { /* not yet implemented */ return 0; } /* remove user subscription */ else if (!_strnicmp(arg,"unsubscribe",11) && (*(arg+11)==';' || *(arg+11)==0)) { /* not yet implemented */ return 0; } return 1; /* parse failed */ } static int JabberLinksModulesLoaded(WPARAM wParam,LPARAM lParam) { char szService[MAXMODULELABELLENGTH]; UNREFERENCED_PARAMETER(wParam); UNREFERENCED_PARAMETER(lParam); mir_snprintf(szService,SIZEOF(szService),"%s%s",jabberProtoName,"ParseXmppURI"); AssocMgr_AddNewUrlType("xmpp:",Translate("Jabber link protocol"),hInst,IDI_JABBER,szService,0); return 0; } int JabberLinksInit() { char szService[MAXMODULELABELLENGTH]; mir_snprintf(szService,SIZEOF(szService),"%s%s",jabberProtoName,"ParseXmppURI"); hServiceParseXmppURI=CreateServiceFunction(szService,ServiceParseXmppURI); hHookModulesLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,JabberLinksModulesLoaded); return 0; } int JabberLinksUninit() { UnhookEvent(hHookModulesLoaded); DestroyServiceFunction(hServiceParseXmppURI); return 0; } #undef hInst #endif // ----------------------------------------- /* static HANDLE hServiceTest; static int TestingService(WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(wParam); MessageBoxEx(NULL, (TCHAR*)lParam, TranslateT("Testing Service"), MB_OK | MB_SETFOREGROUND | MB_TOPMOST | MB_TASKMODAL, LANGIDFROMLCID((LCID)CallService(MS_LANGPACK_GETLOCALE, 0, 0))); return 0; } */ void InitTest(void) { #ifdef AIM_SUPPORT_TEST conn.hInstance=GetModuleHandleA("AIM"); aim_links_init(); #endif #ifdef ICQ_SUPPORT_TEST InitIcqFiles(); #endif #ifdef YAHOO_SUPPORT_TEST YmsgrLinksInit(); #endif #ifdef MSN_SUPPORT_TEST LoadMsnLinks(); #endif #ifdef GG_SUPPORT_TEST gg_registerlinks(); #endif #ifdef JABBER_SUPPORT_TEST JabberLinksInit(); #endif //hServiceTest=CreateServiceFunction("AssocMgr/TestingService",TestingService); //AssocMgr_AddNewFileTypeT(".mir",NULL,TranslateT("Miranda Installer Package (demo purpose)"),TranslateT("&Install"),hInst,IDI_MIRANDAFILE,"AssocMgr/TestingService",0); } void UninitTest(void) { #ifdef AIM_SUPPORT_TEST aim_links_destroy(); #endif #ifdef ICQ_SUPPORT_TEST UninitIcqFiles(); #endif #ifdef YAHOO_SUPPORT_TEST YmsgrLinksUninit(); #endif #ifdef MSN_SUPPORT_TEST UnloadMsnLinks(); #endif #ifdef GG_SUPPORT_TEST gg_unregisterlinks(); #endif #ifdef JABBER_SUPPORT_TEST JabberLinksUninit(); #endif //DestroyServiceFunction(hServiceTest); }