]>
Commit | Line | Data |
---|---|---|
7ac48069 | 1 | /* $Id$ |
2 | * | |
3 | * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology. | |
4 | * For copying and distribution information, please see the file | |
5 | * <mit-copyright.h>. | |
de56407f | 6 | */ |
de56407f | 7 | |
546bc43b | 8 | #include <mit-copyright.h> |
2ad0a777 | 9 | #include <moira.h> |
7ac48069 | 10 | #include "update_server.h" |
11 | ||
7100d074 | 12 | #include <sys/stat.h> |
7ac48069 | 13 | |
14 | #include <errno.h> | |
15 | #include <fcntl.h> | |
16 | #include <stdio.h> | |
17 | #include <string.h> | |
18 | #include <unistd.h> | |
19 | ||
d599d457 | 20 | #include <des.h> |
7ac48069 | 21 | #include <gdb.h> |
7100d074 | 22 | #include <update.h> |
7ac48069 | 23 | |
24 | RCSID("$Header$"); | |
de56407f | 25 | |
26 | extern CONNECTION conn; | |
de56407f | 27 | char buf[BUFSIZ]; |
d599d457 | 28 | extern C_Block session; |
af30a831 | 29 | extern char *whoami; |
de56407f | 30 | |
31 | /* | |
32 | * syntax: | |
33 | * (already sent) pathname file_size checksum | |
34 | * <<< (int)code can we send it? | |
35 | * >>> data | |
36 | * <<< 0 | |
37 | * >>> data | |
38 | * <<< 0 | |
39 | * .... | |
40 | * >>> data (last block) | |
41 | * <<< 0 (on final write, close, sync, checksum) | |
42 | * | |
43 | * returns: | |
44 | * 0 on success | |
45 | * 1 on error (file not found, etc) | |
46 | */ | |
47 | ||
5eaef520 | 48 | int send_file(char *pathname, char *target_path, int encrypt) |
de56407f | 49 | { |
5eaef520 | 50 | int n, fd, code, n_to_send, i; |
51 | STRING data; | |
52 | unsigned char dst[UPDATE_BUFSIZ + 8], *src; | |
53 | struct stat statb; | |
54 | des_key_schedule sched; | |
55 | des_cblock ivec; | |
de56407f | 56 | |
5eaef520 | 57 | /* send file over */ |
58 | fd = open(pathname, O_RDONLY, 0); | |
59 | if (fd < 0) | |
60 | { | |
61 | com_err(whoami, errno, "unable to open %s for read", pathname); | |
62 | return MR_OCONFIG; | |
7100d074 | 63 | } |
5eaef520 | 64 | if (fstat(fd, &statb)) |
65 | { | |
66 | com_err(whoami, errno, "unable to stat %s", pathname); | |
67 | close(fd); | |
68 | return MR_OCONFIG; | |
7100d074 | 69 | } |
5eaef520 | 70 | n_to_send = statb.st_size; |
71 | ||
72 | string_alloc(&data, UPDATE_BUFSIZ); | |
73 | sprintf(STRING_DATA(data), "XFER_00%c %d %d %s", | |
74 | (encrypt ? '3' : '2'), n_to_send, | |
75 | checksum_file(pathname), target_path); | |
76 | code = send_object(conn, (char *)&data, STRING_T); | |
77 | if (code) | |
78 | { | |
79 | com_err(whoami, connection_errno(conn), " sending XFER request"); | |
80 | close(fd); | |
81 | return connection_errno(conn); | |
de56407f | 82 | } |
5eaef520 | 83 | code = receive_object(conn, (char *)&n, INTEGER_T); |
84 | if (code) | |
85 | { | |
86 | com_err(whoami, connection_errno(conn), | |
87 | " getting reply from XFER request"); | |
88 | close(fd); | |
89 | return connection_errno(conn); | |
7100d074 | 90 | } |
5eaef520 | 91 | if (n) |
92 | { | |
93 | com_err(whoami, n, " transfer request (XFER) rejected"); | |
94 | close(fd); | |
95 | return n; | |
7100d074 | 96 | } |
5eaef520 | 97 | |
98 | code = receive_object(conn, (char *)&n, INTEGER_T); | |
99 | if (code) | |
100 | { | |
101 | com_err(whoami, connection_errno(conn), ": lost connection"); | |
102 | close(fd); | |
103 | return connection_errno(conn); | |
de56407f | 104 | } |
5eaef520 | 105 | if (n) |
106 | { | |
107 | com_err(whoami, n, " from remote server: can't update %s", pathname); | |
108 | close(fd); | |
109 | return n; | |
de56407f | 110 | } |
77ac78dc | 111 | |
5eaef520 | 112 | if (encrypt) |
113 | { | |
114 | des_key_sched(session, sched); | |
115 | memmove(ivec, session, sizeof(ivec)); | |
d599d457 | 116 | } |
117 | ||
5eaef520 | 118 | while (n_to_send > 0) |
119 | { | |
120 | n = read(fd, STRING_DATA(data), UPDATE_BUFSIZ); | |
121 | if (n < 0) | |
122 | { | |
123 | com_err(whoami, errno, " reading %s for transmission", pathname); | |
124 | close(fd); | |
125 | return MR_ABORTED; | |
de56407f | 126 | } |
5eaef520 | 127 | MAX_STRING_SIZE(data) = n; |
128 | if (encrypt) | |
129 | { | |
130 | src = (unsigned char *)STRING_DATA(data); | |
131 | memmove(dst, src, n); | |
132 | memset(dst + n, 0, 7); | |
133 | /* encrypt! */ | |
134 | des_pcbc_encrypt(dst, src, n, sched, ivec, 0); | |
135 | /* save vector to continue chaining */ | |
136 | for (i = 0; i < 8; i++) | |
137 | ivec[i] = dst[n - 8 + i] ^ src[n - 8 + i]; | |
138 | /* round up to multiple of 8 */ | |
139 | data.length = (data.length + 7) & 0xfffffff8; | |
d599d457 | 140 | } |
5eaef520 | 141 | code = send_object(conn, (char *)&data, STRING_T); |
142 | if (code) | |
143 | { | |
144 | com_err(whoami, connection_errno(conn), " transmitting file %s", | |
145 | pathname); | |
146 | close(fd); | |
147 | return connection_errno(conn); | |
de56407f | 148 | } |
5eaef520 | 149 | n_to_send -= n; |
150 | code = receive_object(conn, (char *)&n, INTEGER_T); | |
151 | if (code) | |
152 | { | |
153 | com_err(whoami, connection_errno(conn), | |
154 | " awaiting ACK remote server during transmission of %s", | |
155 | pathname); | |
156 | close(fd); | |
157 | return connection_errno(conn); | |
de56407f | 158 | } |
5eaef520 | 159 | if (n) |
160 | { | |
161 | com_err(whoami, n, " from remote server during transmission of %s", | |
162 | pathname); | |
163 | close(fd); | |
164 | return n; | |
de56407f | 165 | } |
166 | } | |
5eaef520 | 167 | if (statb.st_size == 0) |
168 | { | |
169 | code = receive_object(conn, (char *)&n, INTEGER_T); | |
170 | if (code) | |
171 | { | |
172 | com_err(whoami, connection_errno(conn), | |
173 | " awaiting ACK remote server after transmission of %s", | |
174 | pathname); | |
175 | close(fd); | |
176 | return connection_errno(conn); | |
77ac78dc | 177 | } |
5eaef520 | 178 | if (n) |
179 | { | |
180 | com_err(whoami, n, " from remote server after transmission of %s", | |
181 | pathname); | |
182 | close(fd); | |
183 | return n; | |
77ac78dc | 184 | } |
185 | } | |
5eaef520 | 186 | close(fd); |
187 | return MR_SUCCESS; | |
de56407f | 188 | } |