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

📄 gtkphone.c

📁 一款基于GTK的internet phone 程序。程序分为服务器端和客户端两部分。服务器端维护用户的IP
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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 + -