Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабы / 3 / 1.tar / 1 / 1 / net_copy / os_spec

.cpp
Скачиваний:
20
Добавлен:
17.04.2013
Размер:
3.19 Кб
Скачать
/*
  netFileCopyer
  Copyright (C) 2004 Dmitry S. Vasilchenko.

  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; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

  The GNU GPL is contained in /usr/doc/copyright/GPL on a Debian
  system and in the file COPYING in the Linux kernel source.
*/

#include <unistd.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>
#include <resolv.h>

#include <sys/stat.h>

#include <errno.h>
#include <fcntl.h>
#include <signal.h>

#include "os_spec.h"


ssize_t get_fsize(const char *fname)
{
	struct stat mstat;
	if (stat(fname,&mstat) < 0)
		return -1;
	
	return mstat.st_size;
}


int rem_socket()
{
	return socket(PF_INET, SOCK_STREAM, 0);
}

int rem_connect(int sd, const char *ip, int port)
{
	struct sockaddr_in r_addr;
	r_addr.sin_family = AF_INET;
	r_addr.sin_port = htons(port);
	if (inet_aton(ip, &r_addr.sin_addr)==0){
		/* error! */
		return -1;
	}
	
	if (connect(sd,(struct sockaddr *)&r_addr,
			sizeof(r_addr)) == -1){
		/* error! */
		return -1;
	}
	
	return 0;
}

void sig_handler(int signum)
{
	return;
}

int rem_disconnect(int sd)
{	
	signal(SIGPIPE,&sig_handler);
	char dchar;
	//perror("close!");
	//fcntl(sd,F_SETFL,O_NONBLOCK);
	//read(sd,&dchar,1);
	write(sd,&dchar,1);
	//fsync(sd);
	close(sd);
	//read(sd,&dchar,1);
	//write(sd,&dchar,1);
	
	return 0;
}

int rem_send(int sd, const void *buf, ssize_t len)
{
	ssize_t size;
	while ( (size = send(sd, buf, len, MSG_NOSIGNAL)) != len)
		if (size < 0)
			if (errno == EINTR) continue;
			else break;

	return size;
}

int rem_recv(int sd, void *buf, ssize_t len)
{
	ssize_t size;
	while ( (size = recv(sd, buf, len, MSG_WAITALL)) != len)
		if (size <= 0)
			if (errno == EINTR) continue;
			else break;

	return size;
}

int rem_accept(int sd, int port, volatile bool *stopped)
{
	struct sockaddr_in r_addr, c_addr;
	socklen_t addrlen;
	
	memset(&r_addr, 0, sizeof(r_addr));
	r_addr.sin_family = AF_INET;
	r_addr.sin_addr.s_addr = INADDR_ANY;
	r_addr.sin_port = htons(port);
	
	if ( bind(sd, (struct sockaddr *)&r_addr, sizeof(r_addr)) == -1){
		perror("bind");
		return -1;
	}
	
	if (listen(sd, 1) == -1){
		perror("listen");
		return -1;
	}
	
	if (fcntl(sd,F_SETFL,O_NONBLOCK)==-1){
		perror("fcntl");
		return -1;
	}
	
	
	addrlen = sizeof(c_addr);
	int cd;
	while (true){
		if ( (cd = accept(sd, (struct sockaddr *)&c_addr, &addrlen)) == -1)
			if (errno == EAGAIN) usleep(100);
			else if (errno == EINTR) continue;
			else break;
		else break;
		if (*stopped) break;
	}
	
	rem_disconnect(sd);
	
	return cd;	
}
Соседние файлы в папке net_copy