]> andersk Git - moira.git/blame - update/send_file.c
Build without krb4 if it's unavailable.
[moira.git] / update / send_file.c
CommitLineData
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
cb974713 20#ifdef HAVE_KRB4
d599d457 21#include <des.h>
cb974713 22#endif
7100d074 23#include <update.h>
7ac48069 24
25RCSID("$Header$");
de56407f 26
cb974713 27#ifdef HAVE_KRB4
85330553 28extern des_cblock session;
cb974713 29#endif
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
4e3b3c65 48int mr_send_file(int conn, char *pathname, char *target_path, int encrypt)
de56407f 49{
5eaef520 50 int n, fd, code, n_to_send, i;
85330553 51 char data[UPDATE_BUFSIZ], enc[UPDATE_BUFSIZ];
52 long response;
5eaef520 53 struct stat statb;
cb974713 54#ifdef HAVE_KRB4
5eaef520 55 des_key_schedule sched;
56 des_cblock ivec;
cb974713 57#endif
de56407f 58
5eaef520 59 /* send file over */
60 fd = open(pathname, O_RDONLY, 0);
61 if (fd < 0)
62 {
63 com_err(whoami, errno, "unable to open %s for read", pathname);
64 return MR_OCONFIG;
7100d074 65 }
5eaef520 66 if (fstat(fd, &statb))
67 {
68 com_err(whoami, errno, "unable to stat %s", pathname);
69 close(fd);
70 return MR_OCONFIG;
7100d074 71 }
5eaef520 72 n_to_send = statb.st_size;
73
85330553 74 sprintf(data, "XFER_00%c %d %d %s", (encrypt ? '3' : '2'), n_to_send,
5eaef520 75 checksum_file(pathname), target_path);
85330553 76 code = send_string(conn, data, strlen(data) + 1);
5eaef520 77 if (code)
78 {
85330553 79 com_err(whoami, code, "sending XFER request");
5eaef520 80 close(fd);
85330553 81 return code;
de56407f 82 }
85330553 83 code = recv_int(conn, &response);
5eaef520 84 if (code)
85 {
85330553 86 com_err(whoami, code, "getting reply from XFER request");
5eaef520 87 close(fd);
85330553 88 return code;
7100d074 89 }
85330553 90 if (response)
5eaef520 91 {
85330553 92 com_err(whoami, response, "transfer request (XFER) rejected");
5eaef520 93 close(fd);
85330553 94 return response;
7100d074 95 }
5eaef520 96
85330553 97 code = recv_int(conn, &response);
5eaef520 98 if (code)
99 {
85330553 100 com_err(whoami, code, ": lost connection");
5eaef520 101 close(fd);
85330553 102 return code;
de56407f 103 }
85330553 104 if (response)
5eaef520 105 {
85330553 106 com_err(whoami, response, " from remote server: can't update %s",
107 pathname);
5eaef520 108 close(fd);
85330553 109 return response;
de56407f 110 }
77ac78dc 111
5eaef520 112 if (encrypt)
113 {
cb974713 114#ifdef HAVE_KRB4
5eaef520 115 des_key_sched(session, sched);
116 memmove(ivec, session, sizeof(ivec));
cb974713 117#else
118 /* The session key only gets stored if auth happens in krb4 to
119 begin with. If you don't have krb4, you can't possibly be
120 coming up with a valid session key. */
121 return MR_NO_KRB4;
122#endif
d599d457 123 }
124
5eaef520 125 while (n_to_send > 0)
126 {
85330553 127 n = read(fd, data, sizeof(data));
5eaef520 128 if (n < 0)
129 {
85330553 130 com_err(whoami, errno, "reading %s for transmission", pathname);
5eaef520 131 close(fd);
132 return MR_ABORTED;
de56407f 133 }
5eaef520 134 if (encrypt)
135 {
cb974713 136#ifdef HAVE_KRB4
85330553 137 memset(data + n, 0, sizeof(data) -n);
b9b9e340 138 des_pcbc_encrypt(data, enc, (n + 7) & ~7, sched, ivec, 0);
5eaef520 139 /* save vector to continue chaining */
140 for (i = 0; i < 8; i++)
85330553 141 ivec[i] = data[n - 8 + i] ^ enc[n - 8 + i];
5eaef520 142 /* round up to multiple of 8 */
85330553 143 n = (n + 7) & ~7;
144 code = send_string(conn, enc, n);
cb974713 145#endif
d599d457 146 }
85330553 147 else
148 code = send_string(conn, data, n);
5eaef520 149 if (code)
150 {
85330553 151 com_err(whoami, code, "transmitting file %s", pathname);
5eaef520 152 close(fd);
85330553 153 return code;
de56407f 154 }
85330553 155
5eaef520 156 n_to_send -= n;
85330553 157 code = recv_int(conn, &response);
5eaef520 158 if (code)
159 {
85330553 160 com_err(whoami, code, "awaiting ACK during transmission of %s",
5eaef520 161 pathname);
162 close(fd);
85330553 163 return code;
de56407f 164 }
85330553 165 if (response)
5eaef520 166 {
85330553 167 com_err(whoami, response,
168 "from remote server during transmission of %s",
5eaef520 169 pathname);
170 close(fd);
85330553 171 return response;
de56407f 172 }
173 }
85330553 174
5eaef520 175 if (statb.st_size == 0)
176 {
85330553 177 code = recv_int(conn, &response);
5eaef520 178 if (code)
179 {
85330553 180 com_err(whoami, code, "awaiting ACK after transmission of %s",
5eaef520 181 pathname);
182 close(fd);
85330553 183 return code;
77ac78dc 184 }
85330553 185 if (response)
5eaef520 186 {
85330553 187 com_err(whoami, response,
188 "from remote server after transmission of %s",
5eaef520 189 pathname);
190 close(fd);
85330553 191 return response;
77ac78dc 192 }
193 }
5eaef520 194 close(fd);
195 return MR_SUCCESS;
de56407f 196}
This page took 1.068073 seconds and 5 git commands to generate.