📄 gtkphone.c
字号:
/* This is the phone program, written by David Ashley * dash@xdr.com * http://www.xdr.com/dash * This program is released under the terms of the GPL *//* * prototype GTK front end Lee Benfield 06/03/2000 * lee@recoil.org */#include <stdlib.h>#include <gtk/gtk.h>#include "gtkphone.h"#include "phone.h"#include "user_info.h"#define _(x) x#define SERVER "matcher.xdr.com"#define MAXBLOCKS 14#define LISTDELAYTIME 3000/* * Because we can't tell between who and list, we have to send them * quite well spaced. *//* * if we're expecting info about our address book, 0 * if we're expecting a "who's online", 1. */GtkWidget *clist1;GtkWidget *popup_dlg;GtkWidget *online_dlg;GtkWidget *popup_label;char exitflag=0;int talktries=-1;long nextsendtalk;long lastdiff,latency;int block160size;int sndin,sndblocksize;unsigned char sndblock1[16384],sndblock2[16384];char username[MAXNAMESIZE];char calling[MAXNAMESIZE];int tryingtocall=0;unsigned char myhash[8];unsigned char mykey[8];T_bucket userInfo;/* * Gtk dsp callbacks */int incomingDspHandle = 0;int outgoingDspHandle = 0;int connected=0;int gottalk=0;long incount,outcount;#define WRITEFIFOMAX 64unsigned char *writeput,*writetake,*writelimit;int writein;unsigned char writefifo[1024*WRITEFIFOMAX];int loudcount;unsigned char myip[16];int myiplen;long dspopentime;long totalwritten;long totalread;#define PACKETSTOPACK 5unsigned char packed[32+PACKETSTOPACK*33];int packedin;int havedsp=0;opendsp() { int t; int res; int pid; if(havedsp) return 0; sndin=open("/dev/dsp",O_RDWR); if(sndin<0) return -1; /* t=8; res=ioctl(sndin,SNDCTL_DSP_SAMPLESIZE,&t); if(res) return -2; */ t=8000; res=ioctl(sndin,SNDCTL_DSP_SPEED,&t); if(res) return -3; t=1; res=ioctl(sndin,SNDCTL_DSP_CHANNELS,&t); if(res) return -4; res=ioctl(sndin,SNDCTL_DSP_GETFMTS,&t); if(!(t&AFMT_S16_LE)) { printf("Digitizing in 8 bit mode\n"); block160size=160; t=AFMT_U8; res=ioctl(sndin,SNDCTL_DSP_SETFMT,&t); if(res) return -6; t=0x20008; res=ioctl(sndin,SNDCTL_DSP_SETFRAGMENT,&t); if(res) return -5; } else { printf("Digitizing in 16 bit mode\n"); block160size=160*2; t=AFMT_S16_LE; res=ioctl(sndin,SNDCTL_DSP_SETFMT,&t); if(res) return -6; t=0x20009; res=ioctl(sndin,SNDCTL_DSP_SETFRAGMENT,&t); if(res) return -5; } // t=0;res=ioctl(sndin,SNDCTL_DSP_SETFMT,&t); res=ioctl(sndin,SNDCTL_DSP_GETCAPS,&t); if(res) return -7; if(!(t&DSP_CAP_DUPLEX)) { printf("Your soundcard/driver combination isn't allowing full duplex.\n"); printf("That means you can't read from the microphone and write to\n"); printf("the speakers at the same time.\n"); printf("Unfortunately, this program depends on this capability.\n"); return -8; } res=ioctl(sndin,SNDCTL_DSP_GETBLKSIZE,&sndblocksize); if(res) return -9; havedsp=1; incomingDspHandle = gdk_input_add(sndin, GDK_INPUT_READ, incoming_dsp_callback, NULL); // that is, incoming from the microphone. outgoingDspHandle = gdk_input_add(sndin, GDK_INPUT_WRITE, outgoing_dsp_callback, NULL); read(sndin,sndblock1,sndblocksize); writeput=writetake=writefifo; writelimit=writefifo+WRITEFIFOMAX*sndblocksize; writein=0; packedin=0; dspopentime=gtime2(); totalwritten=0; totalread=0; return 0;}tryopendsp() { int result; if(result=opendsp()) { printf("Failed to open dsp, result code %d\n",result); exit(1); } incount=-1; outcount=0;}void dropDspHandles (void) { if (incomingDspHandle) { gdk_input_remove(incomingDspHandle); incomingDspHandle = 0; } if (outgoingDspHandle) { gdk_input_remove(outgoingDspHandle); outgoingDspHandle = 0; }}closedsp() { if(havedsp) { close(sndin); havedsp=0; dropDspHandles(); }}int openserver(char *mname,int port){struct hostent *hostptr;int status; hostptr=gethostbyname(mname); if(!hostptr) { hostptr=gethostbyaddr(mname,strlen(mname),AF_INET); if(!hostptr) return 0; } memset(&servername,0,sizeof(servername)); servername.sin_family=AF_INET; servername.sin_port=htons(port); memcpy(&servername.sin_addr,hostptr->h_addr,hostptr->h_length); return 1;}void messagetoserver(unsigned char *m,int len){unsigned char temp[512],*p,*p2;int i; p=temp; *p++=CODE_CRYPT; memcpy(p,myhash,HASHSIZE);p+=HASHSIZE; p2=p; memcpy(p,specialkey,sizeof(specialkey));p+=sizeof(specialkey); memcpy(p,m,len);p+=len; len+=sizeof(specialkey); while(len&7) { *p++=0; ++len; } i=len; while(--i>0) { p2[1]^=*p2; ++p2; } encryptblock(temp+HASHSIZE+1,len,mykey);/*{int i;for(i=0;i<p-temp;++i) printf(" %02x",temp[i]);printf("\n");}*/ putmsg(&servername,temp,p-temp);}gint populateList(gpointer data) { T_bucket uic = userInfo->next; for ( ; uic ; uic = uic->next ) { char * data[2]; data[0] = uic->online ? "Y" : "N"; data[1] = uic->name; printf ("%s, %s %s\n",data[0],data[1],uic->name); gtk_clist_append(GTK_CLIST(clist1),data); } return FALSE;}gint updateList(gpointer data) { gtk_clist_clear(GTK_CLIST(clist1)); ChainDestroy(userInfo); processtyped(10,""); processtyped(2,""); gtk_timeout_add(LISTDELAYTIME,populateList,NULL); return FALSE;} gint buttonUpdateClist(GtkWidget *widget, gpointer data) { updateList(data); return FALSE;}gint buttonEndConversation(GtkWidget *widget, gpointer data) { processtyped(3,""); return FALSE;}gint answerTalkRequest(GtkWidget *widget, gpointer data) { processtyped(7,""); gtk_widget_hide(popup_dlg); if (GTK_WIDGET_VISIBLE (online_dlg)) { } else { gtk_widget_show(online_dlg); } return FALSE;}gint ignoreTalkRequest(GtkWidget *widget, gpointer data) { gtk_widget_hide(popup_dlg); return FALSE;}gint registerme(gpointer data) { int t; printf ("registerme\n"); mesg[0]=CODE_IAM; memcpy(mesg+1,myip,4); t=ntohs(myname.sin_port); mesg[5]=t>>8; mesg[6]=t; messagetoserver(mesg,1+6); return TRUE;}void unregisterme(void) { int t; printf ("unregisterme\n"); mesg[0]=CODE_IAMNOT; memcpy(mesg+1,myip,4); t=ntohs(myname.sin_port); mesg[5]=t>>8; mesg[6]=t; messagetoserver(mesg,1+6);}gint endProgram( GtkWidget *widget, GdkEvent *event, gpointer data ) { printf ("Main window destroy\n"); unregisterme(); gtk_main_quit();}gint sendtalk(gpointer data) { if (talktries == -1) { printf ("was going to send a talktry, but not needed now.\n"); return FALSE; } if(talktries==MAXTALKTRIES) { printf("No response to TALK request after %d tries. Giving up.\n", talktries); talktries=-1; return FALSE; } ++talktries; mesg[0]=CODE_TALK; memcpy(mesg+1,username,MAXNAMESIZE); mesg[1+MAXNAMESIZE]=0; putmsg(&buddy,mesg,1+MAXNAMESIZE);// nextsendtalk=gtime()+TALKTRYDELAY; return TRUE;}unsigned char myvisibleaddr[IPADDRSIZE];unsigned char myvisibleport[IPPORTSIZE];#define FOUR 0int pack(unsigned char *out,unsigned char *in,int size){int i,j;#if FOUR for(j=i=0;i<size;i+=4) out[j++]=in[i]&0xf0 | ((in[i+2]&0xf0)>>4);#else for(j=i=0;i<size;i+=2) out[j++]=in[i];#endif return j;}int unpack(unsigned char *out,unsigned char *in,int size){int i,j,k;#if FOUR for(j=i=0;i<size;++i) { k=in[i]; out[j++]=k&0xf0; out[j++]=k&0xf0; out[j++]=(k&0x0f)<<4; out[j++]=(k&0x0f)<<4; }#else for(j=i=0;i<size;++i) { k=in[i]; out[j++]=k; out[j++]=k; }#endif return j;}void answer(void){ gottalk=0; talktries=-1; tryopendsp(); if (GTK_WIDGET_VISIBLE (online_dlg)) { } else { gtk_widget_show(online_dlg); } connected=1;}void userprocessmsg(struct sockaddr_in *from,unsigned char *msg,int size) { long int i,j,k; char name[MAXNAMESIZE+1]; char txt[64]; char txt2[64]; unsigned char publicaddr[4]; unsigned char publicport[4]; unsigned char localaddr[4]; unsigned char localport[2]; if(size<1) return; if(*msg==CODE_CRYPT) { ++msg; --size; if(size<sizeof(specialkey)) return; encryptblock(msg,size,mykey); i=size; while(--i>0) { msg[i]^=msg[i-1]; } if(memcmp(msg,specialkey,sizeof(specialkey))) return; msg+=sizeof(specialkey); size-=sizeof(specialkey); } if(size<1) return; --size; switch(*msg++) { case CODE_ENTRY: if(memcmp(&servername.sin_addr.s_addr,&from->sin_addr.s_addr,IPADDRSIZE)) break; if(memcmp(&servername.sin_port,&from->sin_port,IPPORTSIZE)) break; if(size<STATSIZE) break; memcpy(publicaddr,msg,IPADDRSIZE); memcpy(publicport,msg+IPADDRSIZE,IPPORTSIZE); memcpy(localaddr,msg+IPADDRSIZE+IPPORTSIZE,IPADDRSIZE); memcpy(localport,msg+IPADDRSIZE*2+IPPORTSIZE,IPPORTSIZE); memset(name,0,sizeof(name)); memcpy(name,msg+12,MAXNAMESIZE); if(!strcmp(name,username)) { memcpy(myvisibleaddr,publicaddr,IPADDRSIZE); memcpy(myvisibleport,publicport,IPPORTSIZE); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -