3 * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
4 * For copying and distribution information, please see the file
8 #include <mit-copyright.h>
10 #include "update_server.h"
26 extern CONNECTION conn;
28 extern C_Block session;
33 * (already sent) pathname file_size checksum
34 * <<< (int)code can we send it?
40 * >>> data (last block)
41 * <<< 0 (on final write, close, sync, checksum)
45 * 1 on error (file not found, etc)
48 int send_file(char *pathname, char *target_path, int encrypt)
50 int n, fd, code, n_to_send, i;
52 unsigned char dst[UPDATE_BUFSIZ + 8], *src;
54 des_key_schedule sched;
58 fd = open(pathname, O_RDONLY, 0);
61 com_err(whoami, errno, "unable to open %s for read", pathname);
64 if (fstat(fd, &statb))
66 com_err(whoami, errno, "unable to stat %s", pathname);
70 n_to_send = statb.st_size;
72 string_alloc(&data, UPDATE_BUFSIZ);
73 sprintf(STRING_DATA(data), "XFER_00%c %d %d %s",
74 (encrypt ? '3' : '2'), n_to_send,
75 checksum_file(pathname), target_path);
76 code = send_object(conn, (char *)&data, STRING_T);
79 com_err(whoami, connection_errno(conn), " sending XFER request");
81 return connection_errno(conn);
83 code = receive_object(conn, (char *)&n, INTEGER_T);
86 com_err(whoami, connection_errno(conn),
87 " getting reply from XFER request");
89 return connection_errno(conn);
93 com_err(whoami, n, " transfer request (XFER) rejected");
98 code = receive_object(conn, (char *)&n, INTEGER_T);
101 com_err(whoami, connection_errno(conn), ": lost connection");
103 return connection_errno(conn);
107 com_err(whoami, n, " from remote server: can't update %s", pathname);
114 des_key_sched(session, sched);
115 memmove(ivec, session, sizeof(ivec));
118 while (n_to_send > 0)
120 n = read(fd, STRING_DATA(data), UPDATE_BUFSIZ);
123 com_err(whoami, errno, " reading %s for transmission", pathname);
127 MAX_STRING_SIZE(data) = n;
130 src = (unsigned char *)STRING_DATA(data);
131 memmove(dst, src, n);
132 memset(dst + n, 0, 7);
134 des_pcbc_encrypt(dst, src, n, sched, ivec, 0);
135 /* save vector to continue chaining */
136 for (i = 0; i < 8; i++)
137 ivec[i] = dst[n - 8 + i] ^ src[n - 8 + i];
138 /* round up to multiple of 8 */
139 data.length = (data.length + 7) & 0xfffffff8;
141 code = send_object(conn, (char *)&data, STRING_T);
144 com_err(whoami, connection_errno(conn), " transmitting file %s",
147 return connection_errno(conn);
150 code = receive_object(conn, (char *)&n, INTEGER_T);
153 com_err(whoami, connection_errno(conn),
154 " awaiting ACK remote server during transmission of %s",
157 return connection_errno(conn);
161 com_err(whoami, n, " from remote server during transmission of %s",
167 if (statb.st_size == 0)
169 code = receive_object(conn, (char *)&n, INTEGER_T);
172 com_err(whoami, connection_errno(conn),
173 " awaiting ACK remote server after transmission of %s",
176 return connection_errno(conn);
180 com_err(whoami, n, " from remote server after transmission of %s",