]> andersk Git - moira.git/blame - update/get_file.c
cant_fix takes an argument
[moira.git] / update / get_file.c
CommitLineData
de56407f 1/*
2 * $Source$
3 * $Header$
4 */
546bc43b 5/* (c) Copyright 1988 by the Massachusetts Institute of Technology. */
6/* For copying and distribution information, please see the file */
7/* <mit-copyright.h>. */
de56407f 8
9#ifndef lint
10static char *rcsid_get_file_c = "$Header$";
7da203a3 11#endif
de56407f 12
546bc43b 13#include <mit-copyright.h>
de56407f 14#include <stdio.h>
ea579254 15#include <gdb.h>
de56407f 16#include <ctype.h>
698271c7 17#include <string.h>
de56407f 18#include <sys/param.h>
19#include <sys/file.h>
07d1021f 20#include <fcntl.h>
32df7737 21#include <des.h>
22#include <krb.h>
2ad0a777 23#include <moira.h>
de56407f 24#include "update.h"
de56407f 25
7b18e95b 26#ifndef MIN
27#define MIN(a,b) (((a) < (b))?(a):(b))
28#endif /* MIN */
29
de56407f 30extern CONNECTION conn;
7da203a3 31extern char buf[BUFSIZ];
de56407f 32
35fd45e2 33extern int code, errno, uid;
7da203a3 34extern char *whoami;
de56407f 35
36extern int have_authorization, have_file, done;
32df7737 37extern C_Block session;
d599d457 38static des_key_schedule sched;
39static des_cblock ivec;
de56407f 40
7da203a3 41static int get_block();
de56407f 42
43/*
44 * get_file()
45 *
46 * arguments:
47 * char *pathname
48 * file to receive
49 * int file_size
50 * number of bytes
51 * int checksum
52 * linear checksum of bytes
53 *
54 * syntax:
55 * (initial protocol already done)
56 * <<< (int)code (can we accept the file?)
57 * >>> (STRING)data
58 * <<< (int)code
59 * >>> (STRING)data
60 * <<< (int)code
61 * ...
62 * >>> (STRING)data (last data block)
63 * <<< (int)code (from read, write, checksum verify)
64 *
65 * returns:
66 * int
67 * 0 for success, 1 for failure
68 *
69 * function:
70 * perform initial preparations and receive file as
71 * a single string, storing it into <pathname>
72 *
73 */
74
75int
32df7737 76get_file(pathname, file_size, checksum, mode, encrypt)
de56407f 77 char *pathname;
78 int file_size;
79 int checksum;
35fd45e2 80 int mode;
32df7737 81 int encrypt;
de56407f 82{
83 int fd, n_written;
84 int found_checksum;
85
86 if (!have_authorization) {
2ad0a777 87 reject_call(MR_PERM);
de56407f 88 return(1);
89 }
90 if (done) /* re-initialize data */
91 initialize();
698271c7 92#ifdef POSIX
93 if (setuid(uid) < 0) {
94#else
35fd45e2 95 if (setreuid(0, uid) < 0) {
698271c7 96#endif
35fd45e2 97 com_err(whoami, errno, "Unable to setuid to %d\n", uid);
98 exit(1);
99 }
de56407f 100 /* unlink old file */
35fd45e2 101 if (!config_lookup("noclobber"))
102 (void) unlink(pathname);
de56407f 103 /* open file descriptor */
35fd45e2 104 fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode);
de56407f 105 if (fd == -1) {
106 code = errno;
107 sprintf(buf, "%s: creating file %s (get_file)",
108 error_message(code), pathname);
2ad0a777 109 mr_log_error(buf);
de56407f 110 report_error("reporting file creation error (get_file)");
35fd45e2 111 if (setuid(0) < 0) {
112 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
113 exit(1);
114 }
de56407f 115 return(1);
116 }
117 /* check to see if we've got the disk space */
118 n_written = 0;
119 while (n_written < file_size) {
120 register int n_wrote;
121 n_wrote = write(fd, buf, sizeof(buf));
122 if (n_wrote == -1) {
123 code = errno;
124 sprintf(buf, "%s: verifying free disk space for %s (get_file)",
125 error_message(code), pathname);
2ad0a777 126 mr_log_error(buf);
de56407f 127 /* do all we can to free the space */
128 (void) unlink(pathname);
129 (void) ftruncate(fd, 0);
130 (void) close(fd);
131 report_error("reporting test-write error (get_file)");
35fd45e2 132 if (setuid(0) < 0) {
133 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
134 exit(1);
135 }
de56407f 136 return(1);
137 }
138 n_written += n_wrote;
139 }
140 lseek(fd, 0, L_SET);
141 if (send_ok())
142 lose("sending okay for file transfer (get_file)");
d599d457 143 if (encrypt) {
144#ifdef DEBUG
145 com_err(whoami, 0, "Session %02x %02x %02x %02x %02x %02x %02x %02x",
146 session[0], session[1], session[2], session[3],
147 session[4], session[5], session[6], session[7]);
148#endif /* DEBUG */
149 des_key_sched(session, sched);
698271c7 150 memcpy(ivec, session, sizeof(ivec));
d599d457 151 }
de56407f 152 n_written = 0;
153 while (n_written < file_size && code == 0) {
32df7737 154 int n_got = get_block(fd, file_size - n_written, encrypt);
de56407f 155 if (n_got == -1) {
156 /* get_block has already printed a message */
157 unlink(pathname);
35fd45e2 158 if (setuid(0) < 0) {
159 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
160 exit(1);
161 }
de56407f 162 return(1);
163 }
164 n_written += n_got;
165 if (n_written != file_size)
166 if (send_ok())
167 lose("receiving data");
168 }
169 if (code) {
170 code = connection_errno(conn);
171 report_error("reading file (get_file)");
35fd45e2 172 if (setuid(0) < 0) {
173 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
174 exit(1);
175 }
de56407f 176 return(1);
177 }
178 fsync(fd);
179 ftruncate(fd, file_size);
180 fsync(fd);
181 close(fd);
35fd45e2 182 if (setuid(0) < 0) {
183 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
184 exit(1);
185 }
de56407f 186 /* validate checksum */
ea579254 187 found_checksum = checksum_file(pathname);
de56407f 188 if (checksum != found_checksum) {
2ad0a777 189 code = MR_MISSINGFILE;
de56407f 190 com_err(whoami, code, ": expected = %d, found = %d",
191 checksum, found_checksum);
192 report_error("checksum error");
193 return(1);
194 }
de56407f 195 /* send ack or nack */
196 have_file = 1;
197 if (send_ok()) {
198 code = connection_errno(conn);
199 (void) unlink(pathname);
200 lose("sending ok after file transfer (get_file)");
201 return(1);
202 }
203 return(0);
204}
205
206static int
32df7737 207get_block(fd, max_size, encrypt)
de56407f 208 int fd;
209 int max_size;
32df7737 210 int encrypt;
de56407f 211{
212 STRING data;
d599d457 213 unsigned char dst[UPDATE_BUFSIZ + 8], *src;
214 int n_read, n, i;
de56407f 215
216 code = receive_object(conn, (char *)&data, STRING_T);
217 if (code) {
218 code = connection_errno(conn);
219 lose("receiving data file (get_file)");
220 }
32df7737 221
d599d457 222 if (encrypt) {
223 src = (unsigned char *)STRING_DATA(data);
224 n = MAX_STRING_SIZE(data);
225 des_pcbc_encrypt(src, dst, n, sched, ivec, 1);
226 for (i = 0; i < 8; i++)
227 ivec[i] = src[n - 8 + i] ^ dst[n - 8 + i];
698271c7 228 memcpy(STRING_DATA(data), dst, n);
32df7737 229 }
230
d599d457 231 n_read = MIN(MAX_STRING_SIZE(data), max_size);
de56407f 232 n = 0;
233 while (n < n_read) {
234 register int n_wrote;
235 n_wrote = write(fd, STRING_DATA(data)+n,
236 n_read-n);
237 if (n_wrote == -1) {
238 code = errno;
239 sprintf(buf, "%s: writing file (get_file)", error_message(code));
2ad0a777 240 mr_log_error(buf);
de56407f 241 string_free(&data);
242 report_error("reporting write error (get_file)");
243 close(fd);
244 return(-1);
245 }
246 n += n_wrote;
247 }
248 string_free(&data);
249 return(n);
250}
This page took 0.132338 seconds and 5 git commands to generate.