]> andersk Git - moira.git/blob - update/send_file.c
additional arg to send_file()
[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
25
26 extern CONNECTION conn;
27 extern int errno;
28 char buf[BUFSIZ];
29 extern C_Block session;
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
48 int
49 send_file(pathname, target_path, encrypt)
50 char *pathname;
51 char *target_path;
52 int  encrypt;
53 {
54     int n, fd, code, n_to_send, i;
55     STRING data;
56     unsigned char dst[UPDATE_BUFSIZ + 8], *src;
57     struct stat statb;
58     des_key_schedule sched;
59     des_cblock ivec;
60
61     /* send file over */
62     fd = open(pathname, O_RDONLY, 0);
63     if (fd < 0) {
64         com_err(whoami, errno, "unable to open %s for read", pathname);
65         return(MR_OCONFIG);
66     }
67     if (fstat(fd, &statb)) {
68         com_err(whoami, errno, "unable to stat %s", pathname);
69         close(fd);
70         return(MR_OCONFIG);
71     }
72     n_to_send = statb.st_size;
73     
74     string_alloc(&data, UPDATE_BUFSIZ);
75     sprintf(STRING_DATA(data), "XFER_00%c %d %d %s",
76             (encrypt ? '3' : '2'), n_to_send,
77             checksum_file(pathname), target_path);
78     code = send_object(conn, (char *)&data, STRING_T);
79     if (code) {
80         com_err(whoami, code, " sending XFER request");
81         close(fd);
82         return(code);
83     }
84     code = receive_object(conn, (char *)&n, INTEGER_T);
85     if (code) {
86         com_err(whoami, code, " getting reply from XFER request");
87         close(fd);
88         return(code);
89     }
90     if (n) {
91         com_err(whoami, n, " transfer request (XFER) rejected");
92         close(fd);
93         return(n);
94     }
95     
96     code = receive_object(conn, (char *)&n, INTEGER_T);
97     if (code) {
98         com_err(whoami, connection_errno(conn), ": lost connection");
99         close(fd);
100         return(code);
101     }
102     if (n) {
103         com_err(whoami, n, " from remote server: can't update %s",
104                 pathname);
105         close(fd);
106         return(n);
107     }
108
109     if (encrypt) {
110 #ifdef DEBUG
111         printf("Session key %02x %02x %02x %02x  %02x %02x %02x %02x\n",
112                session[0], session[1], session[2], session[3], 
113                session[4], session[5], session[6], session[7]);
114 #endif /* DEBUG */
115         des_key_sched(session, sched);
116         bcopy(session, ivec, sizeof(ivec));
117     }
118
119     while (n_to_send > 0) {
120 #ifdef  DEBUG
121         printf("n_to_send = %d\n", n_to_send);
122 #endif  /* DEBUG */
123         n = read(fd, STRING_DATA(data), UPDATE_BUFSIZ);
124         if (n < 0) {
125             com_err(whoami, errno, " reading %s for transmission", pathname);
126             close(fd);
127             return(MR_ABORTED);
128         }
129         MAX_STRING_SIZE(data) = n;
130         if (encrypt) {
131             src = (unsigned char *)STRING_DATA(data);
132             bcopy(src, dst, n);
133             bzero(dst + n, 7);
134             /* encrypt! */
135             des_pcbc_encrypt(dst, src, n, sched, ivec, 0);
136             /* save vector to continue chaining */
137             for (i = 0; i < 8; i++)
138               ivec[i] = dst[n - 8 + i] ^ src[n - 8 + i];
139             /* round up to multiple of 8 */
140             data.length = (data.length + 7) & 0xfffffff8;
141         }
142         code = send_object(conn, (char *)&data, STRING_T);
143         if (code) {
144             com_err(whoami, connection_errno(conn), " transmitting file %s",
145                     pathname);
146             close(fd);
147             return(code);
148         }
149         n_to_send -= n;
150         code = receive_object(conn, (char *)&n, INTEGER_T);
151         if (code) {
152             com_err(whoami, connection_errno(conn),
153                     " awaiting ACK remote server during transmission of %s",
154                     pathname);
155             close(fd);
156             return(code);
157         }
158         if (n) {
159             com_err(whoami, n, " from remote server during transmission of %s",
160                     pathname);
161             close(fd);
162             return(n);
163         }
164     }
165     if (statb.st_size == 0) {
166         code = receive_object(conn, (char *)&n, INTEGER_T);
167         if (code) {
168             com_err(whoami, connection_errno(conn),
169                     " awaiting ACK remote server after transmission of %s",
170                     pathname);
171             close(fd);
172             return(code);
173         }
174         if (n) {
175             com_err(whoami, n, " from remote server after transmission of %s",
176                     pathname);
177             close(fd);
178             return(n);
179         }
180     }
181     close(fd);
182     return(MR_SUCCESS);
183 }
This page took 1.487831 seconds and 5 git commands to generate.