Edinburgh Speech Tools 2.4-release
 
Loading...
Searching...
No Matches
filetrans.cc
1/*************************************************************************/
2/* */
3/* Centre for Speech Technology Research */
4/* University of Edinburgh, UK */
5/* Copyright (c) 1996 */
6/* All Rights Reserved. */
7/* */
8/* Permission is hereby granted, free of charge, to use and distribute */
9/* this software and its documentation without restriction, including */
10/* without limitation the rights to use, copy, modify, merge, publish, */
11/* distribute, sublicense, and/or sell copies of this work, and to */
12/* permit persons to whom this work is furnished to do so, subject to */
13/* the following conditions: */
14/* 1. The code must retain the above copyright notice, this list of */
15/* conditions and the following disclaimer. */
16/* 2. Any modifications must be clearly marked as such. */
17/* 3. Original authors' names are not deleted. */
18/* 4. The authors' names are not used to endorse or promote products */
19/* derived from this software without specific prior written */
20/* permission. */
21/* */
22/* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23/* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24/* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25/* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26/* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28/* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29/* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30/* THIS SOFTWARE. */
31/* */
32/*************************************************************************/
33/* Author : Alan Black */
34/* Date : December 1996 */
35/*-----------------------------------------------------------------------*/
36/* */
37/* File transfer over open file descriptors. Uses key stuffing */
38/* to allow transfer of any file over an open link (usually a socket) */
39/* */
40/*=======================================================================*/
41#include "EST_unix.h"
42#include <cstdio>
43#include "EST_String.h"
44#include "EST_io_aux.h"
45
46// The following key is used when stuffing files down a socket.
47// This key in when received denotes the end of file. Any occurrence
48// of key in the file with have X inserted in it, and the receiving end
49// with remove that X in the file. This is a technique I learned from
50// HDLC network protocols which guarantees 0x7e (6 bits) starts a header.
51// This allows transfer of files even if they include the stuff key.
52const char *file_stuff_key = "ft_StUfF_key";
53
54static int getc_unbuffered(SOCKET_FD fd)
55{
56 // An attempted to get rid of the buffering
57 char c;
58 int n;
59
60#ifdef WIN32
61 n = recv(fd,&c,1,0);
62#else
63 n = read(fd,&c,1);
64#endif
65
66 if (n == 0) // this isn't necessarily eof
67 return EOF;
68 else
69 return c; // and this might be -1 (EOF)
70}
71
72int socket_receive_file(SOCKET_FD fd,const EST_String &filename)
73{
74 // Copy the file from fd to filename using the 7E stuff key
75 // mechanism so binary files may pass through the socket
76 // without signals or eof.
77 FILE *outfd;
78 int k,i,c;
79
80 if ((outfd=fopen(filename,"wb")) == NULL)
81 {
82 cerr << "socket_receive_file: can't find file \"" <<
83 filename << "\"\n";
84 return -1;
85 }
86
87 k=0;
88 while (file_stuff_key[k] != '\0')
89 {
90 c = getc_unbuffered(fd);
91 if (file_stuff_key[k] == c)
92 k++;
93 else if ((c == 'X') && (file_stuff_key[k+1] == '\0'))
94 {
95 for (i=0; i < k; i++) putc(file_stuff_key[i],outfd);
96 k=0;
97 // omit the stuffed 'X'
98 }
99 else
100 {
101 for (i=0; i < k; i++) putc(file_stuff_key[i],outfd);
102 k=0;
103 putc(c,outfd);
104 }
105 }
106 fclose(outfd);
107 return 0;
108}
109
110int socket_send_file(SOCKET_FD fd,const EST_String &filename)
111{
112 // Send file down fd using the 7E end stuffing technique.
113 // This guarantees the binary transfer without any other
114 // signals eof etc
115#ifndef WIN32
116 FILE *ffd = fdopen(dup(fd),"wb"); // use some buffering
117#endif
118 FILE *infd;
119 int k,c;
120
121 if ((infd=fopen(filename,"rb")) == NULL)
122 {
123 cerr << "socket_send_file: can't find file \"" <<
124 filename << "\"\n";
125 return -1;
126 }
127
128 k=0;
129 while ((c=getc(infd)) != EOF)
130 {
131 if (file_stuff_key[k] == c)
132 k++;
133 else
134 k=0;
135 if (file_stuff_key[k] == '\0')
136 {
137#ifdef WIN32
138 const char filler='X';
139 send(fd,&filler,1,0);
140#else
141 putc('X',ffd); // stuff filler
142#endif
143 k=0;
144 }
145#ifdef WIN32
146 send(fd,(const char *)&c,1,0);
147#else
148 putc(c,ffd);
149#endif
150 }
151 for (k=0; file_stuff_key[k] != '\0'; k++)
152#ifdef WIN32
153 send(fd,file_stuff_key+k,1,0);
154#else
155 putc(file_stuff_key[k],ffd); // stuff whole key as its the end
156
157 fflush(ffd);
158 fclose(ffd);
159#endif
160 fclose(infd);
161 return 0;
162}