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