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