]> andersk Git - moira.git/blob - update/send_file.c
Code style cleanup. (No functional changes)
[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
12
13 #include <mit-copyright.h>
14 #include <stdio.h>
15 #include <com_err.h>
16 #include <gdb.h>
17 #include <moira.h>
18 #include <sys/file.h>
19 #include <sys/stat.h>
20 #include <des.h>
21 #include <krb.h>
22 #include <update.h>
23 #include <fcntl.h>
24
25 extern CONNECTION conn;
26 extern int errno;
27 char buf[BUFSIZ];
28 extern C_Block session;
29 extern char *whoami;
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 send_file(char *pathname, char *target_path, int encrypt)
49 {
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;
56
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;
63     }
64   if (fstat(fd, &statb))
65     {
66       com_err(whoami, errno, "unable to stat %s", pathname);
67       close(fd);
68       return MR_OCONFIG;
69     }
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);
82     }
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);
90     }
91   if (n)
92     {
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     {
101       com_err(whoami, connection_errno(conn), ": lost connection");
102       close(fd);
103       return connection_errno(conn);
104     }
105   if (n)
106     {
107       com_err(whoami, n, " from remote server: can't update %s", pathname);
108       close(fd);
109       return n;
110     }
111
112   if (encrypt)
113     {
114       des_key_sched(session, sched);
115       memmove(ivec, session, sizeof(ivec));
116     }
117
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;
126         }
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;
140         }
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);
148         }
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);
158         }
159       if (n)
160         {
161           com_err(whoami, n, " from remote server during transmission of %s",
162                   pathname);
163           close(fd);
164           return n;
165         }
166     }
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);
177         }
178       if (n)
179         {
180           com_err(whoami, n, " from remote server after transmission of %s",
181                   pathname);
182           close(fd);
183           return n;
184         }
185     }
186   close(fd);
187   return MR_SUCCESS;
188 }
This page took 0.083885 seconds and 5 git commands to generate.