Edinburgh Speech Tools  2.1-release
filetrans.cc
Go to the documentation of this file.
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 using namespace std;
47 
48 // The following key is used when stuffing files down a socket.
49 // This key in when received denotes the end of file. Any occurrence
50 // of key in the file with have X inserted in it, and the receiving end
51 // with remove that X in the file. This is a technique I learned from
52 // HDLC network protocols which guarantees 0x7e (6 bits) starts a header.
53 // This allows transfer of files even if they include the stuff key.
54 const char *file_stuff_key = "ft_StUfF_key";
55 
56 static int getc_unbuffered(SOCKET_FD fd)
57 {
58  // An attempted to get rid of the buffering
59  char c;
60  int n;
61 
62 #ifdef WIN32
63  n = recv(fd,&c,1,0);
64 #else
65  n = read(fd,&c,1);
66 #endif
67 
68  if (n == 0) // this isn't necessarily eof
69  return EOF;
70  else
71  return c; // and this might be -1 (EOF)
72 }
73 
74 int socket_receive_file(SOCKET_FD fd,const EST_String &filename)
75 {
76  // Copy the file from fd to filename using the 7E stuff key
77  // mechanism so binary files may pass through the socket
78  // without signals or eof.
79  FILE *outfd;
80  int k,i,c;
81 
82  if ((outfd=fopen(filename,"wb")) == NULL)
83  {
84  cerr << "socket_receive_file: can't find file \"" <<
85  filename << "\"\n";
86  return -1;
87  }
88 
89  k=0;
90  while (file_stuff_key[k] != '\0')
91  {
92  c = getc_unbuffered(fd);
93  if (file_stuff_key[k] == c)
94  k++;
95  else if ((c == 'X') && (file_stuff_key[k+1] == '\0'))
96  {
97  for (i=0; i < k; i++) putc(file_stuff_key[i],outfd);
98  k=0;
99  // omit the stuffed 'X'
100  }
101  else
102  {
103  for (i=0; i < k; i++) putc(file_stuff_key[i],outfd);
104  k=0;
105  putc(c,outfd);
106  }
107  }
108  fclose(outfd);
109  return 0;
110 }
111 
112 int socket_send_file(SOCKET_FD fd,const EST_String &filename)
113 {
114  // Send file down fd using the 7E end stuffing technique.
115  // This guarantees the binary transfer without any other
116  // signals eof etc
117 #ifndef WIN32
118  SOCKET_FD dupfd = dup(fd);
119  if (dupfd < 0) {
120  cerr << "Error opening file" << endl;
121  return -1;
122  }
123  FILE *ffd = fdopen(dupfd,"wb"); // use some buffering
124 #endif
125  FILE *infd;
126  int k,c;
127 
128  if ((infd=fopen(filename,"rb")) == NULL)
129  {
130  cerr << "socket_send_file: can't find file \"" <<
131  filename << "\"\n";
132 #ifndef WIN32
133  fflush(ffd);
134  fclose(ffd);
135 #endif
136  return -1;
137  }
138 
139  k=0;
140  while ((c=getc(infd)) != EOF)
141  {
142  if (file_stuff_key[k] == c)
143  k++;
144  else
145  k=0;
146  if (file_stuff_key[k] == '\0')
147  {
148 #ifdef WIN32
149  const char filler='X';
150  send(fd,&filler,1,0);
151 #else
152  putc('X',ffd); // stuff filler
153 #endif
154  k=0;
155  }
156 #ifdef WIN32
157  send(fd,(const char *)&c,1,0);
158 #else
159  putc(c,ffd);
160 #endif
161  }
162  for (k=0; file_stuff_key[k] != '\0'; k++)
163 #ifdef WIN32
164  send(fd,file_stuff_key+k,1,0);
165 #else
166  putc(file_stuff_key[k],ffd); // stuff whole key as its the end
167 
168  fflush(ffd);
169  fclose(ffd);
170 #endif
171  fclose(infd);
172  return 0;
173 }
Utility IO Function header file.
const char * file_stuff_key
Definition: filetrans.cc:54
int socket_receive_file(SOCKET_FD fd, const EST_String &filename)
Definition: filetrans.cc:74
NULL
Definition: EST_WFST.cc:55
int SOCKET_FD
Definition: EST_io_aux.h:104
int socket_send_file(SOCKET_FD fd, const EST_String &filename)
Definition: filetrans.cc:112