Ejemplo n.º 1
0
int dealrecvfile(int sockfd)
{
	char name[128];
	int nread,fd;
again:
    if((nread=Readline(sockfd,name,sizeof(name)))>0)
        name[nread-1]='\0';//remove the '\n' fo the tail
	else
	{
        log_msg("client terminated early");
        Close(sockfd);
		exit(1);
	}

    if(access(name,F_OK)==0)//file existed
	{
        Writen(sockfd,error,strlen(error));
		goto again;
	}
    Writen(sockfd,right,strlen(right));
	fd=open(name,O_CREAT|O_WRONLY,S_IRWXU);//在这里不使用包装函数,是为了记录信息
	if(fd<0)
	{
        log_err("connot open file %s",name);
        log_msg("receive file %s failed",name);
		return -1;
	}
	recvfile(sockfd,fd);
    log_msg("receive file %s completed",name);
	Close(fd);
	return 0;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{
    if(argc != 6) {
        die_with_err("Incorrect number of arguments\n"
                     "receiver <filename> <listening_port> <sender_IP> "
                     "<sender_port> <log_filename>");
    }
    FILE *fp = fopen(argv[1], "wb");
    if(fp == nullptr) {
        die_with_err("Failed to creater file");
    }
    FILE *log = (strcmp("stdout", argv[5]) ? fopen(argv[5], "w") : stdout);
    if(log == nullptr) {
        die_with_err("Failed to creater file");
    }
    int recv_sock = udp_init_listen(argv[2]);
    int send_sock = create_tcpsock(argv[3], argv[4]);

    if(recvfile(fp, recv_sock, send_sock, log)) {
        printf("Delivery was unsuccessful\n");
    } else {
        printf("Delivery completed successfully\n");
    }
    fclose(fp);
    if(log != stdout) fclose(log);
    close(recv_sock);
    close(send_sock);
    return 0;
}
Ejemplo n.º 3
0
void *doftp(void *sd)
{
	int req, msg_ok, ret = 0,dump;
	long ssock = (long)sd;

	ret = auth_user(ssock);
	if (ret == -1)
	{
		close(ssock);
		return;
	}

	while(1)
	{
		req = 0;

		if((readn(ssock,(char *)&req,sizeof(req))) < 0)
		{
			printf("server: read error %d\n",errno);
			return;
		}

		req = ntohs(req);
		switch(req)
		{
			case STOREFILE:
				status=sendfile(ssock);
				break;
			case REQUESTFILE:
				status=recvfile(ssock);
				break;
			case MKDIR:
				status=makedir(ssock);
				break;
			case LIST:
				status=listdir(ssock);
				break;
			case DELETEFILE:
				status=deletefile(ssock);
				break;
			case END:
				printf("Client sent request to end connection.\n");
				close(ssock);
				return;
			default:
				break;
		}
		if(status==-1)
			break;
	}
	return;
}
Ejemplo n.º 4
0
void *doftp(void *sd)
{
	int req, msg_ok;
	long ssock = (long)sd;

	auth_user(ssock);

	while(1)
	{
		req = 0;

		if((readn(ssock,(char *)&req,sizeof(req))) < 0)
		{
			printf("server: read error %d\n",errno);
			exit(0);
		}

		req = ntohs(req);
		switch(req)
		{
			case STOREFILE:
				sendfile(ssock);
				break;
			case REQUESTFILE:
				recvfile(ssock);
				break;
			default:
				printf("server: command not supported\n");
				msg_ok = COMMANDNOTSUPPORTED;
				msg_ok = htons(msg_ok);
				if((writen(ssock,(char *)&msg_ok,sizeof(msg_ok))) < 0)
				{
					printf("server: write error :%d\n",errno);
					exit(0);
				}
		}
	}
}
Ejemplo n.º 5
0
/**
  *函数说明:完成从服务器下载文件的过程
  *参数说明:参数1是连接服务器的socket描述符
  */
void download(int st)
{
    //等待服务器返回的可下载文件列表
    struct fileinfo filelist[100];
    memset(filelist, 0, sizeof(filelist));
    recv(st, filelist, sizeof(filelist), 0);

    //获得文件数目,如果为0,那么返回
    if (getfilenum(filelist) == 0)
    {
        printf("server has no file to download\n");
        return;
    }

    //将文件列表显示出来
    showfilelist(filelist);

    //得到一个合法的文件名,将其文件信息发送给服务器
    struct fileinfo file;
    char file_md5_server[100] = {0};//存储服务器文件的md5值
    while(1)
    {
        printf("enter a file name to download:\n");

        //从键盘输入文件名,如果错误,重新输入
        memset(&file, 0, sizeof(file));
        if (getfile(&file) == -1)
        {
            continue;
        }

        send(st, &file, sizeof(file), 0);

        //判断文件是否可以下载,如果可以,那么退出循环
        if (candownload(st, file_md5_server, sizeof(file_md5_server)) == 0)
        {
            break;
        }
    }

    //得到文件的完整路径
    long long filesize = getfilesize(filelist, file.filename);
    char file_dir[128];
    memset(file_dir, 0, sizeof(file_dir));
    strcpy(file_dir, CLIENT_FILES_DIR);
    strcat(file_dir, file.filename);

    //得到该文件在本地的大小,如果不存在,则为0
    struct stat64 filestat;
    long long file_cur_size = 0;
    if (lstat64(file_dir, &filestat) == 0)
    {
        file_cur_size = filestat.st_size;
    }

    //接收文件,如果是正常接收,那么校验MD5
    while (recvfile(file_dir, filesize, file_cur_size, st) == 0)
    {
        //判断md5值是否正确,正确则接收完毕,否则重新接收
        //得到本地文件的md5值
        char file_md5_local[100] = {0};
        getfile_md5(file_dir, file_md5_local);
        if (strcmp(file_md5_local, file_md5_server) == 0)
        {
            printf("check MD5, MD5 is correct!\n");
            //给服务器发送接收完毕信息
            int i = 0;
            send(st, &i, sizeof(i), 0);
            break;
        }
        else
        {
            printf("check MD5, MD5 is not correct!recv agin!\n");
            file_cur_size = 0;
            //给服务器发送重新接收信息
            int i = -1;
            send(st, &i, sizeof(i), 0);
        }
    }
}
Ejemplo n.º 6
0
void do_select(int msock)
{
	int max_fd, msg_ok, ret = 0, req, max_index, i, client_fd, c_len, total_ready;
	fd_set rset, wholeset;
	int client[FD_SETSIZE], n, sock_fd;
	char buffer[MAXLINE];
	struct sockaddr_in client_addr;

	max_fd = msock;
	max_index = -1;

	for(i=0; i<FD_SETSIZE; i++)
		client[i] = -1;

	FD_ZERO(&wholeset);
	FD_SET(msock, &wholeset);

	while (1)
	{
		memcpy(&rset, &wholeset, sizeof(rset));
		total_ready = select(max_fd + 1, &rset, NULL, NULL, NULL);

		if (FD_ISSET(msock, &rset))
		{
			printf("Waiting for client connection\n");
			//accept an incoming connection
			c_len = sizeof(struct sockaddr_in);
			client_fd = accept(msock, (struct sockaddr *)&client_addr, 
					(socklen_t *)&c_len);
			if(client_fd == -1)
			{
				perror("ERROR: accept()\n");
				exit(1);
			}

			ret = auth_user(client_fd);
			if (ret == -1)
				close(client_fd);
			else
			{
				for(i=0; i<FD_SETSIZE; i++)
				{
					if (client[i] < 0)
					{
						client[i] = client_fd;
						break;
					}
				}

				if (i==FD_SETSIZE)
				{
					perror("Too many clients\n");
					exit(1);
				}
				FD_SET(client_fd, &wholeset);

				if (client_fd > max_fd)
					max_fd = client_fd;

				if(i > max_index)
					max_index = i;

				if (--total_ready <= 0)
					continue;
			}
		}

		for(i=0; i<=max_index; i++)
		{
			if ((sock_fd = client[i]) < 0)
				continue;

			if(FD_ISSET(sock_fd, &rset))
			{
				//doftp((void *)(long)sock_fd);
				n = readn(sock_fd,(char *)&req,sizeof(req));

				if(n <= 0)
				{
					close(sock_fd);
					FD_CLR(sock_fd, &wholeset);
					client[i] = -1;

					if (n < 0)
						printf("server: read error %d\n",errno);
					//status=endexecution(option);
				}
				else
				{
					req = ntohs(req);
					switch(req)
					{
					case STOREFILE:
						status=sendfile(sock_fd);
						break;
					case REQUESTFILE:
						status=recvfile(sock_fd);
						break;
					case MKDIR:
						status=makedir(sock_fd);
						break;
					case LIST:
						status=listdir(sock_fd);
						break;
					case DELETEFILE:
						status=deletefile(sock_fd);
						break;
					case END:
						printf("Client sent request to end connection.\n");
						close(sock_fd);
						FD_CLR(sock_fd, &wholeset);
						client[i] = -1;
						break;
					default:
						break;
					}
				}
				if(--total_ready <= 0)
					break;
			}
		}
	}
}
Ejemplo n.º 7
0
/*
 * Receive file(s).
 */
void
get(int argc, char *argv[])
{
	int fd;
	register int n;
	register char *cp;
	char *src;

	if (argc < 2) {
		strcpy(line, "get ");
		printf("(files) ");
		fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		getusage(argv[0]);
		return;
	}
	if (!connected) {
		for (n = 1; n < argc ; n++)
			if (index(argv[n], ':') == 0) {
				getusage(argv[0]);
				return;
			}
	}
	for (n = 1; n < argc ; n++) {
		src = index(argv[n], ':');
		if (src == NULL)
			src = argv[n];
		else {
			struct hostent *hp;

			*src++ = 0;
			hp = gethostbyname(argv[n]);
			if (hp == NULL) {
				fprintf(stderr, "tftp: %s: ", argv[n]);
				herror(NULL);
				continue;
			}
			if (hp->h_length > (int)sizeof(s_inn.sin_addr)) {
				hp->h_length = sizeof(s_inn.sin_addr);
			}
			memcpy(&s_inn.sin_addr, hp->h_addr, hp->h_length);
			s_inn.sin_family = hp->h_addrtype;
			connected = 1;
			strncpy(hostname, hp->h_name, sizeof(hostname));
			hostname[sizeof(hostname)-1] = 0;
		}
		if (argc < 4) {
			cp = argc == 3 ? argv[2] : tail(src);
			fd = creat(cp, 0644);
			if (fd < 0) {
				fprintf(stderr, "tftp: "); perror(cp);
				return;
			}
			if (verbose)
				printf("getting from %s:%s to %s [%s]\n",
					hostname, src, cp, mode);
			s_inn.sin_port = port;
			recvfile(fd, src, mode);
			break;
		}
		cp = tail(src);         /* new .. jdg */
		fd = creat(cp, 0644);
		if (fd < 0) {
			fprintf(stderr, "tftp: "); perror(cp);
			continue;
		}
		if (verbose)
			printf("getting from %s:%s to %s [%s]\n",
				hostname, src, cp, mode);
		s_inn.sin_port = port;
		recvfile(fd, src, mode);
	}
}
Ejemplo n.º 8
0
/*
 * Receive file(s).
 */
void
get(int argc, char *argv[])
{
	int	 fd;
	int	 n;
	char	*cp;
	char	*src;

	if (argc < 2) {
		strlcpy(line, "get ", sizeof(line));
		printf("(files) ");
		readcmd(&line[strlen(line)], LBUFLEN - strlen(line), stdin);
		if (makeargv())
			return;
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		getusage(argv[0]);
		return;
	}
	if (!connected) {
		for (n = 1; n < argc; n++)
			if (strrchr(argv[n], ':') == 0) {
				getusage(argv[0]);
				return;
			}
	}
	for (n = 1; n < argc; n++) {
		src = strrchr(argv[n], ':');
		if (src == NULL)
			src = argv[n];
		else {
			char *cp;

			*src++ = 0;
			cp = argv[n];
			if (cp[0] == '[' && cp[strlen(cp) - 1] == ']') {
				cp[strlen(cp) - 1] = '\0';
				cp++;
			}
			setpeer(cp, NULL);
			if (!connected)
				continue;
		}
		if (argc < 4) {
			cp = argc == 3 ? argv[2] : tail(src);
			fd = open(cp, O_CREAT | O_TRUNC | O_WRONLY, 0644);
			if (fd < 0) {
				warn("create: %s", cp);
				return;
			}
			if (verbose)
				printf("getting from %s:%s to %s [%s]\n",
				    hostname, src, cp, mode);
			recvfile(fd, src, mode);
			break;
		}
		cp = tail(src);	/* new .. jdg */
		fd = open(cp, O_CREAT | O_TRUNC | O_WRONLY, 0644);
		if (fd < 0) {
			warn("create: %s", cp);
			continue;
		}
		if (verbose)
			printf("getting from %s:%s to %s [%s]\n",
			    hostname, src, cp, mode);
		recvfile(fd, src, mode);
	}
}
Ejemplo n.º 9
0
/*
 * Receive file(s).
 */
void
get(int argc, char *argv[])
{
	int	 fd;
	int	 n;
	char	*cp;
	char	*src;

	if (argc < 2) {
		strlcpy(line, "get ", sizeof(line));
		printf("(files) ");
		readcmd(&line[strlen(line)], LBUFLEN - strlen(line), stdin);
		if (makeargv())
			return;
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		getusage(argv[0]);
		return;
	}
	if (!connected) {
		for (n = 1; n < argc; n++)
			if (strchr(argv[n], ':') == 0) {
				getusage(argv[0]);
				return;
			}
	}
	for (n = 1; n < argc; n++) {
		src = strchr(argv[n], ':');
		if (src == NULL)
			src = argv[n];
		else {
			struct hostent	*hp;

			*src++ = 0;
			hp = gethostbyname(argv[n]);
			if (hp == NULL) {
				warnx("%s: %s", argv[n], hstrerror(h_errno));
				continue;
			}
			bcopy(hp->h_addr, (caddr_t)&peeraddr.sin_addr,
			    hp->h_length);
			peeraddr.sin_family = hp->h_addrtype;
			connected = 1;
			strlcpy(hostname, hp->h_name, sizeof(hostname));
		}
		if (argc < 4) {
			cp = argc == 3 ? argv[2] : tail(src);
			fd = creat(cp, 0644);
			if (fd < 0) {
				warn("create: %s", cp);
				return;
			}
			if (verbose)
				printf("getting from %s:%s to %s [%s]\n",
				    hostname, src, cp, mode);
			peeraddr.sin_port = port;
			recvfile(fd, src, mode);
			break;
		}
		cp = tail(src);	/* new .. jdg */
		fd = creat(cp, 0644);
		if (fd < 0) {
			warn("create: %s", cp);
			continue;
		}
		if (verbose)
			printf("getting from %s:%s to %s [%s]\n",
			    hostname, src, cp, mode);
		peeraddr.sin_port = port;
		recvfile(fd, src, mode);
	}
}
Ejemplo n.º 10
0
int
anruf( header_p sys, header_p ich, int lmodem, int tries )
{
	char dialstr[80];
	char lockname[FILENAME_MAX];
	header_p p;
	char *name, *pw;
	const char **v;
	int i, err;
	int dial_cnt = 1;

	/* fuer Janus */
	char *arcer=NULL, *arcerin=NULL, *transfer=NULL, *domain;
	header_p t, d;
	int netcall_error;
	char filename[FILENAME_MAX];
	char tmpname[FILENAME_MAX];
	char outname[FILENAME_MAX];
	char inname[FILENAME_MAX];
	char sysname[FILENAME_MAX];
	struct stat st;
	/* ende fuer Janus */

	t = find(HD_ARCEROUT, sys);
	if (!t) {
		newlog(ERRLOG,
			"Kein ausgehender Packer definiert");
		return 1;
	}
	arcer = t->text;
	strlwr(arcer);

	t = find(HD_ARCERIN, sys);
	if (!t) {
		newlog(ERRLOG,
			"Kein eingehender Packer definiert");
		return 1;
	}
	arcerin = t->text;
	strlwr(arcerin);

	t = find(HD_PROTO, sys);
	if (!t) {
		newlog(ERRLOG,
			"Kein Uebertragungsprotokoll definiert");
		return 1;
	}
	transfer = t->text;
	strlwr(transfer);

	name = NULL;
	p = find(HD_SYS, ich);
	if (p) name = p->text;

	pw = NULL;
	p = find(HD_PASSWD, sys);
	if (p) pw = p->text;

	p = find(HD_X_CALL, sys);
	if (!p) {
		fprintf(stderr, "Welches Netcall-Verfahren????\n");
		exit(20);
	}
	for (i = 0, v = verf; *v; i++, v++)
		if (stricmp(*v, p->text) == 0)
			break;
	if (!*v) return 1;

	if (i < ZCONNECT) {
		t = find(HD_SYS, sys);
		if (!t) {
			newlog(ERRLOG,
				"Illegale Systemdatei: Kein " HN_SYS
				": Header oder falscher Name: %s", filename);
			return 1;
		}
		d = find(HD_DOMAIN, sys);
		if (!d) {
			newlog(ERRLOG,
				"Illegale Systemdatei: Kein " HN_DOMAIN
				": Header: %s", filename);
			return 1;
		}

		for (domain = strtok(d->text, " ;,:");
				domain;
				domain = strtok(NULL, " ;,:")) {
			sprintf(sysname, "%s.%s", t->text, domain);
			strlwr(sysname);
			sprintf(tmpname, "%s/%s", netcalldir, sysname);
			newlog(logname,
				"Suche Verzeichnis, versuche %s...", tmpname);
			if (access(tmpname, R_OK|X_OK) == 0)
				break;
		}

		if(access(tmpname, R_OK|X_OK)) {
			/* Problem: temp. Verzeichnis nicht zu haben */
			newlog(logname,
				"Problem beim Netcall: Verzeichnis "
				"nicht gefunden");
			return 1;
		}
	}

	/* ##### HIER WIRD ANGEWAEHLT ##### */
	p = find(HD_TEL, sys);
	while(tries) {
		if(!p) p = find(HD_TEL, sys);
		make_dialstr(dialstr, sizeof(dialstr), p->text);

		fprintf(stderr, "%3d. Anwahlversuch (noch %d): %-.25s\n",
			dial_cnt++, tries, dialstr);                     

		if (redial(dialstr, lmodem, 1) != 0 ) {
			tries--;
			p = p->other;
		} else {
			/* connect */
			break;
		}
	}

	set_local(lmodem, 0);
	time(&online_start);

	if (i < ZCONNECT) {
		if (name) dfree(name);
		name = dstrdup(boxstat.boxname);
		strupr(name);
#ifdef ENABLE_CAPS_IN_PASSWORD
		strupr(pw);
#endif
	}
	if(login(lmodem, i, name, pw)) return 0;

	if (i < ZCONNECT) { /* JANUS */
		int have_file = 0;

		netcall_error = 0;

		if ( janus_wait(lmodem) != 0 )
			return 0;

		sprintf(tmpname, "%s/%s.%d.dir", netcalldir, sysname, getpid());
		mkdir(tmpname, 0755);
		chdir(tmpname);
		/* outname: ausgehendes Archiv
		 * filename: */
		sprintf(outname, "%s/caller.%s", tmpname, arcer);
		sprintf(filename, "%s/%s.%s", netcalldir, sysname, arcer);
		sprintf(lockname, "%s/%s/" PREARC_LOCK, netcalldir, sysname);
		if (access(filename, R_OK) != 0) {
			FILE *f;
			if(access(filename, F_OK) == 0) {
				newlog(ERRLOG,
					"Leerer Puffer, weil keine Erlaubnis "
					"zum Lesen von %s: %s",
					outname, strerror(errno));
			}

			f = fopen(outname, "wb");
			if (!f) {
				newlog(ERRLOG,
					"Kann Netcall %s nicht erzeugen: %s",
					outname, strerror(errno));
				fclose(deblogfile);
				return 1;
			}
			fputs("\r\n", f);
			fclose(f);
		} else { /* can read filename */
			if (waitnolock(lockname, 180)) {
				fclose(deblogfile);
				newlog(OUTGOING, "System %s Prearc LOCK: %s",
					sysname, lockname );
				return 1;
			}
			fprintf(stderr, "Link: %s -> %s\n",
				filename, outname);
			if(link(filename, outname)) {
				fclose(deblogfile);
				newlog(ERRLOG,
					"Linken: %s -> %s fehlgeschlagen: %s",
					filename, outname, strerror(errno));
				netcall_error = 1;
				goto finish;
			}
			have_file = 1;
		}
		sprintf(inname, "called.%s", arcer);

		st.st_size = 0;
		if(stat(outname, &st)) {
			fprintf(stderr,
				"Zugriff auf %s fehlgeschlagen: %s\n",
				outname, strerror(errno));
			netcall_error = 1;
			goto finish;
		}

		newlog(logname, "Sende %s (%ld Bytes) per %s",
		       outname, (long)st.st_size, transfer);

		err = sendfile(transfer, outname);
		if (err) {
			newlog(logname,
				"Versand der Daten fehlgeschlagen");
			netcall_error = 1;
			goto finish;
		}

		newlog(logname, "Empfange mit %s", transfer);
		if (recvfile(transfer, inname)) {
			newlog(logname,
				"Empfang der Daten fehlgeschlagen");
			netcall_error = 1;
			goto finish;
		}
		st.st_size = 0;
		if(stat(inname, &st)) {
			newlog(logname,
				"Zugriff auf %s fehlgeschlagen: %s",
				inname, strerror(errno));
		}
		newlog(logname, "%ld Bytes empfangen", (long)st.st_size);


	finish:

		/* Fertig, Modem auflegen */
		signal(SIGHUP, SIG_IGN);
		fclose(stdin);
		fclose(stdout);
		hayes_hangup(lmodem); DMLOG("hayes hangup modem");
		hangup(lmodem); DMLOG("hangup modem");
		anrufdauer();

		restore_linesettings(lmodem);
		DMLOG("restoring modem parameters");
		close(lmodem); lmodem=-1; DMLOG("close modem");
		/* neuer stdin */
		fopen("/dev/null", "r");
		/* stderr wird in stdout kopiert */
		dup2(fileno(stderr),fileno(stdout));

		if(!netcall_error) {
			/* Netcall war erfolgreich, also Daten loeschen */
		if(have_file) {
			/* Backups von Nullpuffern sind
			   uninteressant */
			backup3(backoutdir,filename,sysname,arcer);
		}
		/* das ist nur ein Link, den putzen wir weg */
		if ( unlink(outname)) {
			newlog(ERRLOG,
			       "Loeschen von %s fehlgeschlagen: %s",
			       outname, strerror(errno));
		}

		fclose(deblogfile);

		/*
		 * Und empfangene Daten (im Hintergrund) einlesen,
		 * das Modem wird sofort wieder freigegeben.
		 */
		switch(fork()) {
		case -1:
			{ /* cannot fork */
				perror("forking import");
				newlog(ERRLOG,
				       "Forken des Importteils "
				       "fehlgeschlagen: %s",
				       strerror(errno));
				break;
			}
		case 0:
			{
				/* Ich bin child */
				deblogfile=fopen("/tmp/import.deblogfile", "a");
				DMLOG("child forked");
				import_all(arcerin, sysname);
				chdir ("/");
				if(rmdir(tmpname)) {
					newlog(ERRLOG,
						"Loeschen von %s "
						"fehlgeschlagen: %s",
						tmpname, strerror(errno));
				}
				fclose(deblogfile);
				exit(0);
			}
		default: /* parent */
			break;
		}
		}
		return(1);

	} else {
		/* ZCONNECT */

		system_master(ich, sys);
		if (auflegen) return 1;
		bereitstellen();
		files = 1;
		senden_queue = todo;
		todo = NULL;
		while (!auflegen) {
			datei_master(ich, sys);
		}
		anrufdauer();
		close(lmodem); DMLOG("close modem");
		aufraeumen();
		exit (0);
	}

	return 1;
}
Ejemplo n.º 11
0
/*
 * Receive file(s).
 */
void
get (int argc, char *argv[])
{
  int fd;
  register int n;
  register char *cp;
  char *src;

  if (argc < 2)
    get_args ("get", "(files) ", &argc, &argv);

  if (argc < 2)
    {
      getusage (argv[0]);
      return;
    }
  if (!connected)
    {
      for (n = 1; n < argc; n++)
	if (strchr (argv[n], ':') == 0)
	  {
	    getusage (argv[0]);
	    return;
	  }
    }
  for (n = 1; n < argc; n++)
    {
      src = strchr (argv[n], ':');
      if (src == NULL)
	src = argv[n];
      else
	{
	  *src++ = 0;
	  if (resolve_name (argv[n], 0) != RESOLVE_OK)
	    continue;
	}

      if (argc < 4)
	{
	  cp = argc == 3 ? argv[2] : tail (src);
	  fd = creat (cp, 0644);
	  if (fd < 0)
	    {
	      fprintf (stderr, "tftp: ");
	      perror (cp);
	      return;
	    }
	  if (verbose)
	    printf ("getting from %s:%s to %s [%s]\n",
		    hostname, src, cp, mode);
	  peeraddr.sin_port = port ? port : sp->s_port;
	  recvfile (fd, src, mode);
	  break;
	}
      cp = tail (src);		/* new .. jdg */
      fd = creat (cp, 0644);
      if (fd < 0)
	{
	  fprintf (stderr, "tftp: ");
	  perror (cp);
	  continue;
	}
      if (verbose)
	printf ("getting from %s:%s to %s [%s]\n", hostname, src, cp, mode);
      peeraddr.sin_port = port ? port : sp->s_port;
      recvfile (fd, src, mode);
    }
}
Ejemplo n.º 12
0
Archivo: tftp.c Proyecto: solb/nettftp
// Runs the interactive loop and all file transfers.
// Returns: exit status
int main(void)
{
    // Used to control DNS resolution requests:
    struct addrinfo hints;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;

    // Bind to an ephemeral network port:
    struct addrinfo *server = NULL;
    int sfd = openudp(0);
    if(sfd < 0)
        handle_error("bind()");

    // Allocate (small) space to store user input:
    char *buf = malloc(1);
    size_t cap = 1;
    char *cmd; // First word of buf
    size_t len; // Length of cmd

    // Main input loop, which normally only breaks upon a GFO:
    do
    {
        // Keep prompting until the user brings us back something good:
        do
        {
            printf("%s", SHL_PS1);
            readin(&buf, &cap);
        }
        while(homog(buf, ' '));

        // Cleave off the command (first word):
        cmd = strtok(buf, " ");
        len = strlen(cmd);

        if(strncmp(cmd, CMD_CON, len) == 0)
        {
            // Read the arguments:
            const char *hostname = strtok(NULL, " ");
            const char *tmp = strtok(NULL, " ");
            in_port_t port = PORT_UNPRIVILEGED;
            if(tmp)
                port = atoi(tmp);

            // Ensure a hostname or IP has been provided:
            if(!hostname)
            {
                usage(CMD_CON, "hostname", "port");
                continue;
            }

            // Avoid leaking any existing address:
            if(server)
            {
                freeaddrinfo(server);
                server = NULL;
            }

            // Try to resolve the requested hostname:
            if(getaddrinfo(hostname, NULL, &hints, &server))
            {
                fprintf(stderr, "Unable to resolve hostname\n");
                freeaddrinfo(server);
                server = NULL;
                continue;
            }
            ((struct sockaddr_in *)server->ai_addr)->sin_port = htons(port);
        }
        else if(strncmp(cmd, CMD_GET, len) == 0 || strncmp(cmd, CMD_PUT, len) == 0)
        {
            bool putting = strncmp(cmd, CMD_PUT, 1) == 0;

            // Ensure we're already connected to a server:
            if(!server)
            {
                noconn(cmd);
                continue;
            }

            // Make sure we were given a path argument:
            char *pathname = strtok(NULL, "");
            if(!pathname)
            {
                usage(putting ? CMD_PUT : CMD_GET, "pathname", NULL);
                continue;
            }

            // Since basename() might modify pathname, copy it:
            char filename[strlen(pathname)+1];
            memcpy(filename, pathname, sizeof filename);

            int fd;
            if(putting)
            {
                // Try opening the file for reading:
                if((fd = open(pathname, O_RDONLY)) < 0)
                {
                    fprintf(stderr, "local: Unable to read specified file\n");
                    continue;
                }

                // Send a request and record the port used to acknowledge:
                struct sockaddr_in dest_addr;
                sendreq(sfd, basename(filename), OPC_WRQ, server->ai_addr);
                uint8_t *rmtack = recvpkta(sfd, &dest_addr);
                if(iserr(rmtack))
                {
                    fprintf(stderr, "remote: %s\n", strerr(rmtack));
                    free(rmtack);
                    continue;
                }
                free(rmtack);

                // Transmit the file:
                sendfile(sfd, fd, &dest_addr);
            }
            else // getting
            {
                // Try opening a file of that name for writing:
                if((fd = open(basename(filename), O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0)
                {
                    fprintf(stderr, "local: Unable to create the new file\n");
                    continue;
                }

                // Send a request and await the incoming file:
                sendreq(sfd, pathname, OPC_RRQ, server->ai_addr);
                const char *res = recvfile(sfd, fd);
                if(res)
                {
                    fprintf(stderr, "remote: %s\n", res);
                    close(fd);
                    fd = -1;
                    unlink(basename(filename));
                }
            }

            if(fd >= 0)
                close(fd);
        }
        else if(strncmp(cmd, CMD_HLP, len) == 0)
        {
            printf("Commands may be abbreviated.  Commands are:\n\n");
            printf("%s\t\tconnect to remote tftp\n", CMD_CON);
            printf("%s\t\tsend file\n", CMD_PUT);
            printf("%s\t\treceive file\n", CMD_GET);
            printf("%s\t\texit tftp\n", CMD_GFO);
            printf("%s\t\tprint help information\n", CMD_HLP);
        }
        else if(strncmp(cmd, CMD_GFO, len) != 0)
        {
            fprintf(stderr, "%s: unknown directive\n", cmd);
            fprintf(stderr, "Try ? for help.\n");
        }
    }
    while(strncmp(cmd, CMD_GFO, len) != 0);

    free(buf);
    if(server)
        freeaddrinfo(server);

    return 0;
}