5 /* (c) Copyright 1988 by the Massachusetts Institute of Technology. */
6 /* For copying and distribution information, please see the file */
7 /* <mit-copyright.h>. */
10 static char *rcsid_send_file_c = "$Header$";
13 #include <mit-copyright.h>
28 extern CONNECTION conn;
31 extern C_Block session;
35 * (already sent) pathname file_size checksum
36 * <<< (int)code can we send it?
42 * >>> data (last block)
43 * <<< 0 (on final write, close, sync, checksum)
47 * 1 on error (file not found, etc)
51 send_file(pathname, target_path, encrypt)
56 int n, fd, code, n_to_send, i;
58 unsigned char dst[UPDATE_BUFSIZ + 8], *src;
60 des_key_schedule sched;
64 fd = open(pathname, O_RDONLY, 0);
66 com_err(whoami, errno, "unable to open %s for read", pathname);
69 if (fstat(fd, &statb)) {
70 com_err(whoami, errno, "unable to stat %s", pathname);
74 n_to_send = statb.st_size;
76 string_alloc(&data, UPDATE_BUFSIZ);
77 sprintf(STRING_DATA(data), "XFER_00%c %d %d %s",
78 (encrypt ? '3' : '2'), n_to_send,
79 checksum_file(pathname), target_path);
80 code = send_object(conn, (char *)&data, STRING_T);
82 com_err(whoami, connection_errno(conn), " sending XFER request");
84 return(connection_errno(conn));
86 code = receive_object(conn, (char *)&n, INTEGER_T);
88 com_err(whoami, connection_errno(conn),
89 " getting reply from XFER request");
91 return(connection_errno(conn));
94 com_err(whoami, n, " transfer request (XFER) rejected");
99 code = receive_object(conn, (char *)&n, INTEGER_T);
101 com_err(whoami, connection_errno(conn), ": lost connection");
103 return(connection_errno(conn));
106 com_err(whoami, n, " from remote server: can't update %s",
114 printf("Session key %02x %02x %02x %02x %02x %02x %02x %02x\n",
115 session[0], session[1], session[2], session[3],
116 session[4], session[5], session[6], session[7]);
118 des_key_sched(session, sched);
120 memmove(ivec, session, sizeof(ivec));
122 bcopy(session, ivec, sizeof(ivec));
126 while (n_to_send > 0) {
128 printf("n_to_send = %d\n", n_to_send);
130 n = read(fd, STRING_DATA(data), UPDATE_BUFSIZ);
132 com_err(whoami, errno, " reading %s for transmission", pathname);
136 MAX_STRING_SIZE(data) = n;
138 src = (unsigned char *)STRING_DATA(data);
140 memmove(dst, src, n);
144 memset(dst + n, 0, 7);
146 des_pcbc_encrypt(dst, src, n, sched, ivec, 0);
147 /* save vector to continue chaining */
148 for (i = 0; i < 8; i++)
149 ivec[i] = dst[n - 8 + i] ^ src[n - 8 + i];
150 /* round up to multiple of 8 */
151 data.length = (data.length + 7) & 0xfffffff8;
153 code = send_object(conn, (char *)&data, STRING_T);
155 com_err(whoami, connection_errno(conn), " transmitting file %s",
158 return(connection_errno(conn));
161 code = receive_object(conn, (char *)&n, INTEGER_T);
163 com_err(whoami, connection_errno(conn),
164 " awaiting ACK remote server during transmission of %s",
167 return(connection_errno(conn));
170 com_err(whoami, n, " from remote server during transmission of %s",
176 if (statb.st_size == 0) {
177 code = receive_object(conn, (char *)&n, INTEGER_T);
179 com_err(whoami, connection_errno(conn),
180 " awaiting ACK remote server after transmission of %s",
183 return(connection_errno(conn));
186 com_err(whoami, n, " from remote server after transmission of %s",