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>
18 #include <sys/param.h>
27 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
30 extern CONNECTION conn;
31 extern char buf[BUFSIZ];
33 extern int code, errno, uid;
36 extern int have_authorization, have_file, done;
37 extern C_Block session;
38 static des_key_schedule sched;
39 static des_cblock ivec;
41 static int get_block();
52 * linear checksum of bytes
55 * (initial protocol already done)
56 * <<< (int)code (can we accept the file?)
62 * >>> (STRING)data (last data block)
63 * <<< (int)code (from read, write, checksum verify)
67 * 0 for success, 1 for failure
70 * perform initial preparations and receive file as
71 * a single string, storing it into <pathname>
75 int get_file(char *pathname, int file_size, int checksum,
76 int mode, int encrypt)
81 if (!have_authorization)
86 if (done) /* re-initialize data */
90 com_err(whoami, errno, "Unable to setuid to %d\n", uid);
94 if (!config_lookup("noclobber"))
96 /* open file descriptor */
97 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)");
107 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
112 /* check to see if we've got the disk space */
114 while (n_written < file_size)
117 n_wrote = write(fd, buf, sizeof(buf));
121 sprintf(buf, "%s: verifying free disk space for %s (get_file)",
122 error_message(code), pathname);
124 /* do all we can to free the space */
128 report_error("reporting test-write error (get_file)");
131 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
136 n_written += n_wrote;
140 lose("sending okay for file transfer (get_file)");
143 des_key_sched(session, sched);
144 memcpy(ivec, session, sizeof(ivec));
147 while (n_written < file_size && code == 0)
149 int n_got = get_block(fd, file_size - n_written, encrypt);
152 /* get_block has already printed a message */
156 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
162 if (n_written != file_size)
165 lose("receiving data");
170 code = connection_errno(conn);
171 report_error("reading file (get_file)");
174 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
180 ftruncate(fd, file_size);
185 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
188 /* validate checksum */
189 found_checksum = checksum_file(pathname);
190 if (checksum != found_checksum)
192 code = MR_MISSINGFILE;
193 com_err(whoami, code, ": expected = %d, found = %d",
194 checksum, found_checksum);
195 report_error("checksum error");
198 /* send ack or nack */
202 code = connection_errno(conn);
204 lose("sending ok after file transfer (get_file)");
210 static int get_block(int fd, int max_size, int encrypt)
213 unsigned char dst[UPDATE_BUFSIZ + 8], *src;
216 code = receive_object(conn, (char *)&data, STRING_T);
219 code = connection_errno(conn);
220 lose("receiving data file (get_file)");
225 src = (unsigned char *)STRING_DATA(data);
226 n = MAX_STRING_SIZE(data);
227 des_pcbc_encrypt(src, dst, n, sched, ivec, 1);
228 for (i = 0; i < 8; i++)
229 ivec[i] = src[n - 8 + i] ^ dst[n - 8 + i];
230 memcpy(STRING_DATA(data), dst, n);
233 n_read = MIN(MAX_STRING_SIZE(data), max_size);
238 n_wrote = write(fd, STRING_DATA(data) + n, n_read - n);
242 sprintf(buf, "%s: writing file (get_file)", error_message(code));
245 report_error("reporting write error (get_file)");