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>
25 #define MIN(a,b) (((a) < (b))?(a):(b))
28 extern CONNECTION conn;
31 extern int code, errno, uid;
33 extern int have_authorization, have_file, done;
34 extern C_Block session;
47 * linear checksum of bytes
50 * (initial protocol already done)
51 * <<< (int)code (can we accept the file?)
57 * >>> (STRING)data (last data block)
58 * <<< (int)code (from read, write, checksum verify)
62 * 0 for success, 1 for failure
65 * perform initial preparations and receive file as
66 * a single string, storing it into <pathname>
71 get_file(pathname, file_size, checksum, mode, encrypt)
81 if (!have_authorization) {
85 if (done) /* re-initialize data */
87 if (setreuid(0, uid) < 0) {
88 com_err(whoami, errno, "Unable to setuid to %d\n", uid);
92 if (!config_lookup("noclobber"))
93 (void) unlink(pathname);
94 /* open file descriptor */
95 fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode);
98 sprintf(buf, "%s: creating file %s (get_file)",
99 error_message(code), pathname);
101 report_error("reporting file creation error (get_file)");
103 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
108 /* check to see if we've got the disk space */
110 while (n_written < file_size) {
111 register int n_wrote;
112 n_wrote = write(fd, buf, sizeof(buf));
115 sprintf(buf, "%s: verifying free disk space for %s (get_file)",
116 error_message(code), pathname);
118 /* do all we can to free the space */
119 (void) unlink(pathname);
120 (void) ftruncate(fd, 0);
122 report_error("reporting test-write error (get_file)");
124 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
129 n_written += n_wrote;
133 lose("sending okay for file transfer (get_file)");
135 while (n_written < file_size && code == 0) {
136 int n_got = get_block(fd, file_size - n_written, encrypt);
138 /* get_block has already printed a message */
141 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
147 if (n_written != file_size)
149 lose("receiving data");
152 code = connection_errno(conn);
153 report_error("reading file (get_file)");
155 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
161 ftruncate(fd, file_size);
165 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
168 /* validate checksum */
169 found_checksum = checksum_file(pathname);
170 if (checksum != found_checksum) {
171 code = MR_MISSINGFILE;
172 com_err(whoami, code, ": expected = %d, found = %d",
173 checksum, found_checksum);
174 report_error("checksum error");
177 /* send ack or nack */
180 code = connection_errno(conn);
181 (void) unlink(pathname);
182 lose("sending ok after file transfer (get_file)");
189 get_block(fd, max_size, encrypt)
197 code = receive_object(conn, (char *)&data, STRING_T);
199 code = connection_errno(conn);
200 lose("receiving data file (get_file)");
202 n_read = MIN(MAX_STRING_SIZE(data), max_size);
204 des_key_schedule sched;
208 des_key_sched(session, sched);
209 bzero(ivec, sizeof(ivec));
210 STRING_DATA(newdata) = (char *) malloc(n_read+9);
211 des_pcbc_encrypt(STRING_DATA(data), STRING_DATA(newdata),
212 n_read, sched, &ivec, 1);
214 data.ptr = newdata.ptr;
219 register int n_wrote;
220 n_wrote = write(fd, STRING_DATA(data)+n,
224 sprintf(buf, "%s: writing file (get_file)", error_message(code));
227 report_error("reporting write error (get_file)");