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"
28 extern des_cblock 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 mr_send_file(int conn, char *pathname, char *target_path, int encrypt)
50 int n, fd, code, n_to_send, i;
51 char data[UPDATE_BUFSIZ], enc[UPDATE_BUFSIZ];
55 des_key_schedule sched;
60 fd = open(pathname, O_RDONLY, 0);
63 com_err(whoami, errno, "unable to open %s for read", pathname);
66 if (fstat(fd, &statb))
68 com_err(whoami, errno, "unable to stat %s", pathname);
72 n_to_send = statb.st_size;
74 sprintf(data, "XFER_00%c %d %d %s", (encrypt ? '3' : '2'), n_to_send,
75 checksum_file(pathname), target_path);
76 code = send_string(conn, data, strlen(data) + 1);
79 com_err(whoami, code, "sending XFER request");
83 code = recv_int(conn, &response);
86 com_err(whoami, code, "getting reply from XFER request");
92 com_err(whoami, response, "transfer request (XFER) rejected");
97 code = recv_int(conn, &response);
100 com_err(whoami, code, ": lost connection");
106 com_err(whoami, response, " from remote server: can't update %s",
115 des_key_sched(session, sched);
116 memmove(ivec, session, sizeof(ivec));
118 /* The session key only gets stored if auth happens in krb4 to
119 begin with. If you don't have krb4, you can't possibly be
120 coming up with a valid session key. */
125 while (n_to_send > 0)
127 n = read(fd, data, sizeof(data));
130 com_err(whoami, errno, "reading %s for transmission", pathname);
137 memset(data + n, 0, sizeof(data) -n);
138 des_pcbc_encrypt(data, enc, (n + 7) & ~7, sched, ivec, 0);
139 /* save vector to continue chaining */
140 for (i = 0; i < 8; i++)
141 ivec[i] = data[n - 8 + i] ^ enc[n - 8 + i];
142 /* round up to multiple of 8 */
144 code = send_string(conn, enc, n);
148 code = send_string(conn, data, n);
151 com_err(whoami, code, "transmitting file %s", pathname);
157 code = recv_int(conn, &response);
160 com_err(whoami, code, "awaiting ACK during transmission of %s",
167 com_err(whoami, response,
168 "from remote server during transmission of %s",
175 if (statb.st_size == 0)
177 code = recv_int(conn, &response);
180 com_err(whoami, code, "awaiting ACK after transmission of %s",
187 com_err(whoami, response,
188 "from remote server after transmission of %s",