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