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