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 memset(buf, '\0', sizeof(buf));
75 if (!have_authorization)
77 send_int(conn, MR_PERM);
82 com_err(whoami, errno, "Unable to setuid to %d\n", uid);
87 if (!config_lookup("noclobber"))
89 /* open file descriptor */
90 fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode);
94 com_err(whoami, errno, "creating file %s (get_file)", pathname);
99 /* check to see if we've got the disk space */
101 while (n_written < file_size)
104 n_wrote = write(fd, buf, sizeof(buf));
108 com_err(whoami, code, "verifying free disk space for %s (get_file)",
110 send_int(conn, code);
112 /* do all we can to free the space */
118 n_written += n_wrote;
121 lseek(fd, 0, SEEK_SET);
126 des_key_sched(session, sched);
127 memcpy(ivec, session, sizeof(ivec));
131 while (n_written < file_size)
133 int n_got = get_block(conn, fd, file_size - n_written, encrypt);
137 /* get_block has already printed a message */
142 if (n_written != file_size)
147 ftruncate(fd, file_size);
151 /* validate checksum */
152 found_checksum = checksum_file(pathname);
153 if (checksum != found_checksum)
155 code = MR_MISSINGFILE;
156 com_err(whoami, code, ": expected = %d, found = %d",
157 checksum, found_checksum);
158 send_int(conn, code);
166 static int get_block(int conn, int fd, int max_size, int encrypt)
170 int n_read, n, i, code;
172 recv_string(conn, &data, &len);
176 char *unenc = malloc(len);
180 send_int(conn, ENOMEM);
184 des_pcbc_encrypt(data, unenc, len, sched, ivec, 1);
185 for (i = 0; i < 8; i++)
186 ivec[i] = data[len - 8 + i] ^ unenc[len - 8 + i];
191 n_read = MIN(len, max_size);
196 n_wrote = write(fd, data + n, n_read - n);
200 com_err(whoami, errno, "writing file (get_file)");
201 send_int(conn, code);