]> andersk Git - moira.git/blob - update/get_file.c
added copyright message
[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 <sms.h>
20 #include "update.h"
21 #include "kludge.h"
22
23 extern CONNECTION conn;
24 char buf[BUFSIZ];
25
26 extern int code, errno;
27
28 extern int have_authorization, have_file, done;
29
30 int 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
64 int
65 get_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) {
74         reject_call(SMS_PERM);
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 */
136     found_checksum = checksum_file(pathname);
137     if (checksum != found_checksum) {
138         code = SMS_MISSINGFILE;
139         com_err(whoami, code, ": expected = %d, found = %d",
140                 checksum, found_checksum);
141         report_error("checksum error");
142         return(1);
143     }
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
155 static int
156 get_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.07486 seconds and 5 git commands to generate.