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"
25 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
28 static des_key_schedule sched;
29 static des_cblock ivec;
30 extern des_cblock session;
32 static int get_block(int conn, int fd, int max_size, int encrypt);
43 * linear checksum of bytes
46 * (initial protocol already done)
47 * <<< (int)code (can we accept the file?)
53 * >>> (STRING)data (last data block)
54 * <<< (int)code (from read, write, checksum verify)
58 * 0 for success, 1 for failure
61 * perform initial preparations and receive file as
62 * a single string, storing it into <pathname>
66 int get_file(int conn, char *pathname, int file_size, int checksum,
67 int mode, int encrypt)
69 int fd, n_written, code;
73 if (!have_authorization)
75 send_int(conn, MR_PERM);
80 com_err(whoami, errno, "Unable to setuid to %d\n", uid);
85 if (!config_lookup("noclobber"))
87 /* open file descriptor */
88 fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode);
92 com_err(whoami, errno, "creating file %s (get_file)", pathname);
97 /* check to see if we've got the disk space */
99 while (n_written < file_size)
102 n_wrote = write(fd, buf, sizeof(buf));
106 com_err(whoami, code, "verifying free disk space for %s (get_file)",
108 send_int(conn, code);
110 /* do all we can to free the space */
116 n_written += n_wrote;
119 lseek(fd, 0, SEEK_SET);
124 des_key_sched(session, sched);
125 memcpy(ivec, session, sizeof(ivec));
129 while (n_written < file_size)
131 int n_got = get_block(conn, fd, file_size - n_written, encrypt);
135 /* get_block has already printed a message */
140 if (n_written != file_size)
145 ftruncate(fd, file_size);
149 /* validate checksum */
150 found_checksum = checksum_file(pathname);
151 if (checksum != found_checksum)
153 code = MR_MISSINGFILE;
154 com_err(whoami, code, ": expected = %d, found = %d",
155 checksum, found_checksum);
156 send_int(conn, code);
164 static int get_block(int conn, int fd, int max_size, int encrypt)
168 int n_read, n, i, code;
170 recv_string(conn, &data, &len);
174 char *unenc = malloc(len);
178 send_int(conn, ENOMEM);
182 des_pcbc_encrypt(data, unenc, len, sched, ivec, 1);
183 for (i = 0; i < 8; i++)
184 ivec[i] = data[len - 8 + i] ^ unenc[len - 8 + i];
189 n_read = MIN(len, max_size);
194 n_wrote = write(fd, data + n, n_read - n);
198 com_err(whoami, errno, "writing file (get_file)");
199 send_int(conn, code);