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

📄 cdnsclient.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************  CDnsClient.c  Network component  (c) 2003-2004 Daniel Campos Fernández <danielcampos@netcourrier.com>  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 1, 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; if not, write to the Free Software  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __CDNSCLIENT_C#include <stdio.h>#include <stdlib.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/poll.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <semaphore.h>#include <pthread.h>#include <errno.h>#include "main.h"#include "CDnsClient.h"#ifndef _REENTRANT#define _REENTRANT#endifvoid **dns_object=NULL;int dns_count=0;sem_t dns_th_pipe;int dns_r_pipe=-1;int dns_w_pipe=-1;DECLARE_EVENT (Finished);/********************************************************** DnsClient pipe message protocol: 1) (void*)DNSCLIENT* 2) Action : '0' --> dns_get_name, '1' --> dns_get_ip 3) Result : string finished with '\x10' *********************************************************/void dns_callback(long lParam){	/***********************************************************	This function reads a message sent by a thread, and then	raises "Finished" event if necessary, and fills HostName	and HostIP properties. This function will run on the main	thread.	************************************************************/	CDNSCLIENT *mythis;	void *v_obj;	char Action[1];	char BufRead[1];	char *Buf=NULL;	int Position;	int myloop;	int test_id;	struct pollfd mypoll;	int idata=1;	if (dns_r_pipe==-1) return;	sem_wait(&dns_th_pipe);	while (1)	{		Position=0;		BufRead[0]='\0';		mypoll.fd=dns_r_pipe;		mypoll.events=POLLIN;		mypoll.revents=0;		idata=poll(&mypoll,1,0);		if (!idata) break;		read (dns_r_pipe,&v_obj,sizeof(void*));		read (dns_r_pipe,&test_id,sizeof(int));		read (dns_r_pipe,Action,sizeof(char));		GB.Alloc((void**)&Buf,sizeof(char));		while (BufRead[0] != '\x10')		{			read(dns_r_pipe,BufRead,sizeof(char));			if (BufRead[0]!='\x10')			{				Buf[Position]=BufRead[0];				Position++;				GB.Realloc((void**)&Buf,(Position+1)*sizeof(char));			}			else				Buf[Position]='\0';		}		Position=-1;		for (myloop=0;myloop<dns_count;myloop++)		{			if ( dns_object[myloop]==v_obj)			{				Position=myloop;				break;			}		}		if ( Position>=0)		{			mythis=(CDNSCLIENT*)v_obj;			if (mythis->iStatus && (mythis->i_id==test_id))			{				if (Action[0]=='1')				{					GB.FreeString(&mythis->sHostIP);					GB.NewString(&mythis->sHostIP, Buf ,0);				}				else				{					GB.FreeString(&mythis->sHostName);					GB.NewString(&mythis->sHostName,Buf,0);				}				mythis->iStatus=0;				if (mythis->finished_callback)				{				  GB.Ref(mythis);				  GB.Post(mythis->finished_callback, (long)mythis->CliParent);				}				else				{					GB.Ref(mythis);					GB.Post((void (*)())dns_event, (long)mythis);				}			}		}		GB.Free((void**)&Buf);	}	sem_post(&dns_th_pipe);}/************************************************** To raise an event **************************************************/void dns_event(CDNSCLIENT *mythis){    GB.Raise(mythis,Finished,0);    GB.Unref((void**)&mythis);}void* dns_get_name(void* v_obj){	/****************************************************************	This function will run in a thread different from main thread,	   and when it finish its proccess, it sends a message to the	   main thread using a pipe	*****************************************************************/	char Buf[1];	int myid;	int res;	CDNSCLIENT *mythis;	char host[1024];	struct sockaddr_in sa;		pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);	Buf[0]='0';	mythis=(CDNSCLIENT*)v_obj;	sem_wait(&mythis->sem_id);	myid=mythis->i_id;	sem_post(&mythis->sem_id);	((struct sockaddr*)&sa)->sa_family=AF_INET;	bzero(host,1024);	sa.sin_port=0;	inet_aton(mythis->sHostIP, &sa.sin_addr);		res=getnameinfo((struct sockaddr*)&sa,sizeof(struct sockaddr_in),host,1024*sizeof(char),NULL,0,NI_NAMEREQD);		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);	sem_wait(&dns_th_pipe);	write (dns_w_pipe,&v_obj,sizeof(void*)); /* object */	write (dns_w_pipe,&myid,sizeof(int));    /* id */	write (dns_w_pipe,Buf,sizeof(char));     /* Action */	if (!res) write (dns_w_pipe,host,strlen(host)*sizeof(char));	write (dns_w_pipe,"\x10",sizeof(char));	sem_post(&dns_th_pipe);	return NULL;}/****************************************************************This function will run in a thread different from main thread,and when it finish its proccess, it sends a message to themain thread using a pipe*****************************************************************/void* dns_get_ip(void* v_obj){		char Buf[1];	char *BufData;	int myid;	struct addrinfo *stHost;	struct sockaddr_in *addr;	CDNSCLIENT *mythis;		pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);		Buf[0]='1';	mythis=(CDNSCLIENT*)v_obj;	sem_wait(&mythis->sem_id);	myid=mythis->i_id;	sem_post(&mythis->sem_id);	if (getaddrinfo(mythis->sHostName,NULL,NULL,&stHost)) stHost=NULL;	if (stHost) if ( stHost[0].ai_family!=PF_INET ) stHost=NULL;	sem_wait(&dns_th_pipe);	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);	write (dns_w_pipe,&v_obj,sizeof(void*)); /* object */	write (dns_w_pipe,&myid,sizeof(int));    /* id */	write (dns_w_pipe,Buf,sizeof(char));     /* action */	if (stHost!=NULL)	{		addr=(struct sockaddr_in*)stHost[0].ai_addr;		BufData=inet_ntoa(addr->sin_addr);		if (BufData) write (dns_w_pipe,BufData,strlen(BufData)*sizeof(char));	}	write (dns_w_pipe,"\x10",sizeof(char));	sem_post(&dns_th_pipe);	return NULL;}void dns_close_all(CDNSCLIENT *mythis){	if (mythis->iStatus)  	{		pthread_cancel(mythis->th_id); /* cancel thread */		pthread_join(mythis->th_id,NULL);		sem_destroy(&mythis->sem_id);		mythis->iStatus=0; /* inactive */		dns_callback(dns_r_pipe); /* freeing pipe data */	}}int dns_thread_getname(CDNSCLIENT *mythis){	sem_wait(&mythis->sem_id);	mythis->i_id++;	sem_post(&mythis->sem_id);	mythis->iStatus=1;	if (pthread_create(&mythis->th_id,NULL,dns_get_name,(void*)mythis) )	{		mythis->iStatus=0;		return 1;	}	pthread_detach(mythis->th_id);	return 0;}int dns_thread_getip(CDNSCLIENT *mythis){	sem_wait(&mythis->sem_id);	mythis->i_id++;	sem_post(&mythis->sem_id);	mythis->iStatus=1;	if (pthread_create(&mythis->th_id,NULL,dns_get_ip,(void*)mythis) )	{		mythis->iStatus=0;		return 1;	}	pthread_detach(mythis->th_id);	return 0;}int dns_set_async_mode(int myval,CDNSCLIENT *mythis){	int dpipe[2];	if (myval && (dns_r_pipe==-1))	{		if (pipe(dpipe)) return 1;		dns_r_pipe=dpipe[0];		dns_w_pipe=dpipe[1];		sem_init(&dns_th_pipe,0,1);		GB.Watch(dns_r_pipe , GB_WATCH_READ , (void *)dns_callback,0);	}	mythis->iAsync=myval;	return 0;}/*************************************************************************************######################################################################################	---------------------  DNSCLIENT GAMBAS INTERFACE IMPLEMENTATION -----------------######################################################################################**************************************************************************************//********************************************* This property gets/sets the name of a Host *********************************************/BEGIN_PROPERTY ( HostName )	if (READ_PROPERTY)  	{		if (THIS->iStatus){ GB.ReturnString(NULL); return; }		GB.ReturnString(THIS->sHostName);		return;	}	if (THIS->iStatus) { GB.Error("HostIP can not be changed while working"); return;}	GB.FreeString(&THIS->sHostName);	GB.StoreString(PROP(GB_STRING), &THIS->sHostName);END_PROPERTY/************************************************* This property gets/sets the IP address of a Host *************************************************/BEGIN_PROPERTY ( HostIP )	if (READ_PROPERTY)

⌨️ 快捷键说明

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