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