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_get_file_c = "$Header$";
13 #include <mit-copyright.h>
17 #include <sys/param.h>
26 #define MIN(a,b) (((a) < (b))?(a):(b))
29 extern CONNECTION conn;
32 extern int code, errno, uid;
34 extern int have_authorization, have_file, done;
35 extern C_Block session;
36 static des_key_schedule sched;
37 static des_cblock ivec;
50 * linear checksum of bytes
53 * (initial protocol already done)
54 * <<< (int)code (can we accept the file?)
60 * >>> (STRING)data (last data block)
61 * <<< (int)code (from read, write, checksum verify)
65 * 0 for success, 1 for failure
68 * perform initial preparations and receive file as
69 * a single string, storing it into <pathname>
74 get_file(pathname, file_size, checksum, mode, encrypt)
84 if (!have_authorization) {
88 if (done) /* re-initialize data */
90 if (setreuid(0, uid) < 0) {
91 com_err(whoami, errno, "Unable to setuid to %d\n", uid);
95 if (!config_lookup("noclobber"))
96 (void) unlink(pathname);
97 /* open file descriptor */
98 fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode);
101 sprintf(buf, "%s: creating file %s (get_file)",
102 error_message(code), pathname);
104 report_error("reporting file creation error (get_file)");
106 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
111 /* check to see if we've got the disk space */
113 while (n_written < file_size) {
114 register int n_wrote;
115 n_wrote = write(fd, buf, sizeof(buf));
118 sprintf(buf, "%s: verifying free disk space for %s (get_file)",
119 error_message(code), pathname);
121 /* do all we can to free the space */
122 (void) unlink(pathname);
123 (void) ftruncate(fd, 0);
125 report_error("reporting test-write error (get_file)");
127 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
132 n_written += n_wrote;
136 lose("sending okay for file transfer (get_file)");
139 com_err(whoami, 0, "Session %02x %02x %02x %02x %02x %02x %02x %02x",
140 session[0], session[1], session[2], session[3],
141 session[4], session[5], session[6], session[7]);
143 des_key_sched(session, sched);
144 bcopy(session, ivec, sizeof(ivec));
147 while (n_written < file_size && code == 0) {
148 int n_got = get_block(fd, file_size - n_written, encrypt);
150 /* get_block has already printed a message */
153 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
159 if (n_written != file_size)
161 lose("receiving data");
164 code = connection_errno(conn);
165 report_error("reading file (get_file)");
167 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
173 ftruncate(fd, file_size);
177 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
180 /* validate checksum */
181 found_checksum = checksum_file(pathname);
182 if (checksum != found_checksum) {
183 code = MR_MISSINGFILE;
184 com_err(whoami, code, ": expected = %d, found = %d",
185 checksum, found_checksum);
186 report_error("checksum error");
189 /* send ack or nack */
192 code = connection_errno(conn);
193 (void) unlink(pathname);
194 lose("sending ok after file transfer (get_file)");
201 get_block(fd, max_size, encrypt)
207 unsigned char dst[UPDATE_BUFSIZ + 8], *src;
210 code = receive_object(conn, (char *)&data, STRING_T);
212 code = connection_errno(conn);
213 lose("receiving data file (get_file)");
217 src = (unsigned char *)STRING_DATA(data);
218 n = MAX_STRING_SIZE(data);
219 des_pcbc_encrypt(src, dst, n, sched, ivec, 1);
220 for (i = 0; i < 8; i++)
221 ivec[i] = src[n - 8 + i] ^ dst[n - 8 + i];
222 bcopy(dst, STRING_DATA(data), n);
225 n_read = MIN(MAX_STRING_SIZE(data), max_size);
228 register int n_wrote;
229 n_wrote = write(fd, STRING_DATA(data)+n,
233 sprintf(buf, "%s: writing file (get_file)", error_message(code));
236 report_error("reporting write error (get_file)");