]> andersk Git - moira.git/blame - update/get_file.c
use CODE=ANSI_C option to proc
[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
5eaef520 27#define MIN(a, b) (((a) < (b)) ? (a) : (b))
7b18e95b 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
5eaef520 75int get_file(char *pathname, int file_size, int checksum,
76 int mode, int encrypt)
de56407f 77{
5eaef520 78 int fd, n_written;
79 int found_checksum;
80
81 if (!have_authorization)
82 {
83 reject_call(MR_PERM);
84 return 1;
de56407f 85 }
5eaef520 86 if (done) /* re-initialize data */
87 initialize();
88 if (setuid(uid) < 0)
89 {
90 com_err(whoami, errno, "Unable to setuid to %d\n", uid);
91 exit(1);
35fd45e2 92 }
5eaef520 93 /* unlink old file */
94 if (!config_lookup("noclobber"))
95 unlink(pathname);
96 /* open file descriptor */
97 fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode);
98 if (fd == -1)
99 {
100 code = errno;
101 sprintf(buf, "%s: creating file %s (get_file)",
102 error_message(code), pathname);
103 mr_log_error(buf);
104 report_error("reporting file creation error (get_file)");
105 if (setuid(0) < 0)
106 {
107 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
108 exit(1);
35fd45e2 109 }
5eaef520 110 return 1;
de56407f 111 }
5eaef520 112 /* check to see if we've got the disk space */
113 n_written = 0;
114 while (n_written < file_size)
115 {
44d12d58 116 int n_wrote;
5eaef520 117 n_wrote = write(fd, buf, sizeof(buf));
118 if (n_wrote == -1)
119 {
120 code = errno;
121 sprintf(buf, "%s: verifying free disk space for %s (get_file)",
122 error_message(code), pathname);
123 mr_log_error(buf);
124 /* do all we can to free the space */
125 unlink(pathname);
126 ftruncate(fd, 0);
127 close(fd);
128 report_error("reporting test-write error (get_file)");
129 if (setuid(0) < 0)
130 {
131 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
132 exit(1);
35fd45e2 133 }
5eaef520 134 return 1;
de56407f 135 }
5eaef520 136 n_written += n_wrote;
de56407f 137 }
5eaef520 138 lseek(fd, 0, L_SET);
139 if (send_ok())
140 lose("sending okay for file transfer (get_file)");
141 if (encrypt)
142 {
143 des_key_sched(session, sched);
144 memcpy(ivec, session, sizeof(ivec));
d599d457 145 }
5eaef520 146 n_written = 0;
147 while (n_written < file_size && code == 0)
148 {
149 int n_got = get_block(fd, file_size - n_written, encrypt);
150 if (n_got == -1)
151 {
152 /* get_block has already printed a message */
153 unlink(pathname);
154 if (setuid(0) < 0)
155 {
156 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
157 exit(1);
35fd45e2 158 }
5eaef520 159 return 1;
160 }
161 n_written += n_got;
162 if (n_written != file_size)
163 {
164 if (send_ok())
165 lose("receiving data");
de56407f 166 }
de56407f 167 }
5eaef520 168 if (code)
169 {
170 code = connection_errno(conn);
171 report_error("reading file (get_file)");
172 if (setuid(0) < 0)
173 {
174 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
175 exit(1);
35fd45e2 176 }
5eaef520 177 return 1;
de56407f 178 }
5eaef520 179 fsync(fd);
180 ftruncate(fd, file_size);
181 fsync(fd);
182 close(fd);
183 if (setuid(0) < 0)
184 {
185 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
186 exit(1);
35fd45e2 187 }
5eaef520 188 /* validate checksum */
189 found_checksum = checksum_file(pathname);
190 if (checksum != found_checksum)
191 {
192 code = MR_MISSINGFILE;
193 com_err(whoami, code, ": expected = %d, found = %d",
194 checksum, found_checksum);
195 report_error("checksum error");
196 return 1;
de56407f 197 }
5eaef520 198 /* send ack or nack */
199 have_file = 1;
200 if (send_ok())
201 {
202 code = connection_errno(conn);
203 unlink(pathname);
204 lose("sending ok after file transfer (get_file)");
205 return 1;
de56407f 206 }
5eaef520 207 return 0;
de56407f 208}
209
5eaef520 210static int get_block(int fd, int max_size, int encrypt)
de56407f 211{
5eaef520 212 STRING data;
213 unsigned char dst[UPDATE_BUFSIZ + 8], *src;
214 int n_read, n, i;
de56407f 215
5eaef520 216 code = receive_object(conn, (char *)&data, STRING_T);
217 if (code)
218 {
219 code = connection_errno(conn);
220 lose("receiving data file (get_file)");
de56407f 221 }
32df7737 222
5eaef520 223 if (encrypt)
224 {
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);
32df7737 231 }
232
5eaef520 233 n_read = MIN(MAX_STRING_SIZE(data), max_size);
234 n = 0;
235 while (n < n_read)
236 {
44d12d58 237 int n_wrote;
5eaef520 238 n_wrote = write(fd, STRING_DATA(data) + n, n_read - n);
239 if (n_wrote == -1)
240 {
241 code = errno;
242 sprintf(buf, "%s: writing file (get_file)", error_message(code));
243 mr_log_error(buf);
244 string_free(&data);
245 report_error("reporting write error (get_file)");
246 close(fd);
247 return -1;
de56407f 248 }
5eaef520 249 n += n_wrote;
de56407f 250 }
5eaef520 251 string_free(&data);
252 return n;
de56407f 253}
This page took 0.118472 seconds and 5 git commands to generate.