]> andersk Git - moira.git/blob - update/get_file.c
Initial revision
[moira.git] / update / get_file.c
1 /*
2  *      $Source$
3  *      $Header$
4  */
5 /*  (c) Copyright 1988 by the Massachusetts Institute of Technology. */
6 /*  For copying and distribution information, please see the file */
7 /*  <mit-copyright.h>. */
8
9 #ifndef lint
10 static char *rcsid_get_file_c = "$Header$";
11 #endif  lint
12
13 #include <mit-copyright.h>
14 #include <stdio.h>
15 #include <gdb.h>
16 #include <ctype.h>
17 #include <sys/param.h>
18 #include <sys/file.h>
19 #include <moira.h>
20 #include "update.h"
21
22 extern CONNECTION conn;
23 char buf[BUFSIZ];
24
25 extern int code, errno;
26
27 extern int have_authorization, have_file, done;
28
29 int 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
63 int
64 get_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) {
73         reject_call(MR_PERM);
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);
86         mr_log_error(buf);
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);
99             mr_log_error(buf);
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 */
135     found_checksum = checksum_file(pathname);
136     if (checksum != found_checksum) {
137         code = MR_MISSINGFILE;
138         com_err(whoami, code, ": expected = %d, found = %d",
139                 checksum, found_checksum);
140         report_error("checksum error");
141         return(1);
142     }
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
154 static int
155 get_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));
176             mr_log_error(buf);
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 0.049793 seconds and 5 git commands to generate.