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