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