]> andersk Git - moira.git/blame - update/get_file.c
Fix a pile of error messages.
[moira.git] / update / get_file.c
CommitLineData
7ac48069 1/* $Id$
2 *
3 * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
4 * For copying and distribution information, please see the file
5 * <mit-copyright.h>.
de56407f 6 */
de56407f 7
546bc43b 8#include <mit-copyright.h>
2ad0a777 9#include <moira.h>
7ac48069 10#include "update_server.h"
de56407f 11#include "update.h"
de56407f 12
7ac48069 13#include <errno.h>
14#include <fcntl.h>
15#include <stdio.h>
85330553 16#include <stdlib.h>
eedd0489 17#include <string.h>
7ac48069 18#include <unistd.h>
19
20#include <des.h>
7ac48069 21
22RCSID("$Header$");
23
7b18e95b 24#ifndef MIN
5eaef520 25#define MIN(a, b) (((a) < (b)) ? (a) : (b))
7b18e95b 26#endif /* MIN */
27
d599d457 28static des_key_schedule sched;
29static des_cblock ivec;
85330553 30extern des_cblock session;
de56407f 31
85330553 32static int get_block(int conn, int fd, int max_size, int encrypt);
de56407f 33
34/*
35 * get_file()
36 *
37 * arguments:
38 * char *pathname
39 * file to receive
40 * int file_size
41 * number of bytes
42 * int checksum
43 * linear checksum of bytes
44 *
45 * syntax:
46 * (initial protocol already done)
47 * <<< (int)code (can we accept the file?)
48 * >>> (STRING)data
49 * <<< (int)code
50 * >>> (STRING)data
51 * <<< (int)code
52 * ...
53 * >>> (STRING)data (last data block)
54 * <<< (int)code (from read, write, checksum verify)
55 *
56 * returns:
57 * int
58 * 0 for success, 1 for failure
59 *
60 * function:
61 * perform initial preparations and receive file as
62 * a single string, storing it into <pathname>
63 *
64 */
65
85330553 66int get_file(int conn, char *pathname, int file_size, int checksum,
5eaef520 67 int mode, int encrypt)
de56407f 68{
85330553 69 int fd, n_written, code;
5eaef520 70 int found_checksum;
85330553 71 char buf[BUFSIZ];
5eaef520 72
0a01a5a4 73 memset(buf, '\0', sizeof(buf));
74
5eaef520 75 if (!have_authorization)
76 {
85330553 77 send_int(conn, MR_PERM);
5eaef520 78 return 1;
de56407f 79 }
5eaef520 80 if (setuid(uid) < 0)
81 {
82 com_err(whoami, errno, "Unable to setuid to %d\n", uid);
83 exit(1);
35fd45e2 84 }
85330553 85
5eaef520 86 /* unlink old file */
87 if (!config_lookup("noclobber"))
88 unlink(pathname);
89 /* open file descriptor */
90 fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode);
91 if (fd == -1)
92 {
93 code = errno;
85330553 94 com_err(whoami, errno, "creating file %s (get_file)", pathname);
95 send_int(conn, code);
5eaef520 96 return 1;
de56407f 97 }
85330553 98
5eaef520 99 /* check to see if we've got the disk space */
100 n_written = 0;
101 while (n_written < file_size)
102 {
44d12d58 103 int n_wrote;
5eaef520 104 n_wrote = write(fd, buf, sizeof(buf));
105 if (n_wrote == -1)
106 {
107 code = errno;
85330553 108 com_err(whoami, code, "verifying free disk space for %s (get_file)",
109 pathname);
110 send_int(conn, code);
111
5eaef520 112 /* do all we can to free the space */
113 unlink(pathname);
114 ftruncate(fd, 0);
115 close(fd);
5eaef520 116 return 1;
de56407f 117 }
5eaef520 118 n_written += n_wrote;
de56407f 119 }
85330553 120
7ac48069 121 lseek(fd, 0, SEEK_SET);
85330553 122 send_ok(conn);
123
5eaef520 124 if (encrypt)
125 {
126 des_key_sched(session, sched);
127 memcpy(ivec, session, sizeof(ivec));
d599d457 128 }
85330553 129
5eaef520 130 n_written = 0;
85330553 131 while (n_written < file_size)
5eaef520 132 {
85330553 133 int n_got = get_block(conn, fd, file_size - n_written, encrypt);
134
5eaef520 135 if (n_got == -1)
136 {
137 /* get_block has already printed a message */
138 unlink(pathname);
5eaef520 139 return 1;
140 }
141 n_written += n_got;
142 if (n_written != file_size)
85330553 143 send_ok(conn);
de56407f 144 }
85330553 145
5eaef520 146 fsync(fd);
147 ftruncate(fd, file_size);
148 fsync(fd);
149 close(fd);
85330553 150
5eaef520 151 /* validate checksum */
152 found_checksum = checksum_file(pathname);
153 if (checksum != found_checksum)
154 {
155 code = MR_MISSINGFILE;
156 com_err(whoami, code, ": expected = %d, found = %d",
157 checksum, found_checksum);
85330553 158 send_int(conn, code);
5eaef520 159 return 1;
de56407f 160 }
85330553 161
162 send_ok(conn);
5eaef520 163 return 0;
de56407f 164}
165
85330553 166static int get_block(int conn, int fd, int max_size, int encrypt)
de56407f 167{
85330553 168 char *data;
169 size_t len;
170 int n_read, n, i, code;
de56407f 171
85330553 172 recv_string(conn, &data, &len);
32df7737 173
5eaef520 174 if (encrypt)
175 {
85330553 176 char *unenc = malloc(len);
177
178 if (!unenc)
179 {
180 send_int(conn, ENOMEM);
181 return -1;
182 }
183
184 des_pcbc_encrypt(data, unenc, len, sched, ivec, 1);
5eaef520 185 for (i = 0; i < 8; i++)
85330553 186 ivec[i] = data[len - 8 + i] ^ unenc[len - 8 + i];
187 free(data);
188 data = unenc;
32df7737 189 }
190
85330553 191 n_read = MIN(len, max_size);
5eaef520 192 n = 0;
193 while (n < n_read)
194 {
44d12d58 195 int n_wrote;
85330553 196 n_wrote = write(fd, data + n, n_read - n);
5eaef520 197 if (n_wrote == -1)
198 {
199 code = errno;
85330553 200 com_err(whoami, errno, "writing file (get_file)");
201 send_int(conn, code);
202 free(data);
5eaef520 203 close(fd);
204 return -1;
de56407f 205 }
5eaef520 206 n += n_wrote;
de56407f 207 }
85330553 208 free(data);
5eaef520 209 return n;
de56407f 210}
This page took 0.133708 seconds and 5 git commands to generate.