]> andersk Git - moira.git/blob - update/send_file.c
Initial revision
[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 <update.h>
22
23
24 extern CONNECTION conn;
25 extern int errno;
26 char buf[BUFSIZ];
27
28 /*
29  * syntax:
30  * (already sent) pathname file_size checksum
31  * <<< (int)code                        can we send it?
32  * >>> data
33  * <<< 0
34  * >>> data
35  * <<< 0
36  * ....
37  * >>> data                             (last block)
38  * <<< 0        (on final write, close, sync, checksum)
39  *
40  * returns:
41  *  0 on success
42  *  1 on error (file not found, etc)
43  */
44
45 int
46 send_file(pathname, target_path)
47 char *pathname;
48 char *target_path;
49 {
50     int n, fd, code, n_to_send;
51     STRING data;
52     struct stat statb;
53
54     string_alloc(&data, UPDATE_BUFSIZ);
55
56     /* send file over */
57     fd = open(pathname, O_RDONLY, 0);
58     if (fd < 0) {
59         com_err(whoami, errno, "unable to open %s for read", pathname);
60         return(MR_OCONFIG);
61     }
62     if (fstat(fd, &statb)) {
63         com_err(whoami, errno, "unable to stat %s", pathname);
64         close(fd);
65         return(MR_OCONFIG);
66     }
67     n_to_send = statb.st_size;
68     
69     sprintf(STRING_DATA(data), "XFER_002 %d %d %s",
70             n_to_send, checksum_file(pathname), target_path);
71     code = send_object(conn, (char *)&data, STRING_T);
72     if (code) {
73         com_err(whoami, code, " sending XFER_002 request");
74         close(fd);
75         return(code);
76     }
77     code = receive_object(conn, (char *)&n, INTEGER_T);
78     if (code) {
79         com_err(whoami, code, " getting reply from XFER_002 request");
80         close(fd);
81         return(code);
82     }
83     if (n) {
84         com_err(whoami, n, " transfer request (XFER_002) rejected");
85         close(fd);
86         return(n);
87     }
88     
89     code = receive_object(conn, (char *)&n, INTEGER_T);
90     if (code) {
91         com_err(whoami, connection_errno(conn), ": lost connection");
92         close(fd);
93         return(code);
94     }
95     if (n) {
96         com_err(whoami, n, " from remote server: can't update %s",
97                 pathname);
98         close(fd);
99         return(n);
100     }
101
102     while (n_to_send > 0) {
103 #ifdef  DEBUG
104         printf("n_to_send = %d\n", n_to_send);
105 #endif  /* DEBUG */
106         n = read(fd, STRING_DATA(data), UPDATE_BUFSIZ);
107         if (n < 0) {
108             com_err(whoami, errno, " reading %s for transmission", pathname);
109             close(fd);
110             return(MR_ABORTED);
111         }
112         MAX_STRING_SIZE(data) = n;
113         code = send_object(conn, (char *)&data, STRING_T);
114         if (code) {
115             com_err(whoami, connection_errno(conn), " transmitting file %s",
116                     pathname);
117             close(fd);
118             return(code);
119         }
120         n_to_send -= n;
121         code = receive_object(conn, (char *)&n, INTEGER_T);
122         if (code) {
123             com_err(whoami, connection_errno(conn),
124                     " awaiting ACK remote server during transmission of %s",
125                     pathname);
126             close(fd);
127             return(code);
128         }
129         if (n) {
130             com_err(whoami, n, " from remote server during transmission of %s",
131                     pathname);
132             close(fd);
133             return(n);
134         }
135     }
136     if (statb.st_size == 0) {
137         code = receive_object(conn, (char *)&n, INTEGER_T);
138         if (code) {
139             com_err(whoami, connection_errno(conn),
140                     " awaiting ACK remote server after transmission of %s",
141                     pathname);
142             close(fd);
143             return(code);
144         }
145         if (n) {
146             com_err(whoami, n, " from remote server after transmission of %s",
147                     pathname);
148             close(fd);
149             return(n);
150         }
151     }
152     close(fd);
153     return(MR_SUCCESS);
154 }
This page took 0.117863 seconds and 5 git commands to generate.