]> andersk Git - moira.git/blob - update/client.c
use TCP keepalives on the update connection
[moira.git] / update / client.c
1 /*
2  *      $Source$
3  *      $Header$
4  */
5
6 #ifndef lint
7 static char *rcsid_client2_c = "$Header$";
8 #endif  lint
9
10 /*
11  * MODULE IDENTIFICATION:
12  *      $Header$
13  *      Copyright 1987, 1988 by the Massachusetts Institute of Technology.
14  *      For copying and distribution information, please see the file
15  *      <mit-copyright.h>.
16  * DESCRIPTION:
17  *      This code handles the actual distribution of data files
18  *      to servers in the SMS server-update program.
19  * AUTHOR:
20  *      Ken Raeburn (spook@athena.MIT.EDU),
21  *              MIT Project Athena/MIT Information Systems.
22  * DEFINED VALUES:
23  *      conn
24  *      sms_update_server
25  */
26
27 #include <mit-copyright.h>
28 #include <stdio.h>
29 #include <strings.h>
30 #include <gdb.h>
31 #include <sys/param.h>
32 #include <sys/wait.h>
33 #include <sys/socket.h>
34 #include <update.h>
35 #include <errno.h>
36 #include <dcm.h>
37 #include <sms.h>
38 #include <krb.h>
39
40 extern char *malloc();
41 extern int errno, dbg;
42
43 static char buf[BUFSIZ];
44 static int code;
45
46 CONNECTION conn;
47
48
49 /*
50  * FUNCTION:
51  *      initialize()
52  * DESCRIPTION:
53  *      Insures that various libraries have a chance to get
54  *      initialized.
55  * INPUT:
56  * OUTPUT:
57  * RETURN VALUE:
58  *      void
59  * SIDE EFFECTS:
60  *      Initializes GDB library.
61  * PROBLEMS:
62  *
63  */
64 static void
65 initialize()
66 {
67     static int initialized = 0;
68
69     if (!initialized) {
70         gdb_init();
71         initialized++;
72     }
73 }
74
75
76 /*
77  * FUNCTION:
78  *      sms_update_server(service, machine, target_path)
79  * DESCRIPTION:
80  *      Attempts to perform an update to the named machine
81  *      of the named service.  The file SMS_DIR/dcm/service.out
82  *      will be sent, then the file SMS_DIR/bin/service.sh,
83  *      the the shell script will be executed.
84  * INPUT:
85  *      service
86  *              Name of service to be updated; used to find
87  *              the source data file in the SMS data directory.
88  *      machine
89  *      target_path
90  *              Location to install the file.
91  * RETURN VALUE:
92  *      int:
93  *              Error code, or zero if no error was detected
94  *              in the data supplied to this routine.
95  * SIDE EFFECTS:
96  *      May write information to logs.
97  * PROBLEMS:
98  *
99  */
100
101 int
102 sms_update_server(service, machine, target_path, instructions)
103 char *service;
104 char *machine;
105 char *target_path;
106 char *instructions;
107 {
108 #define ASSERT(condition,stat,amsg) \
109     if (!(condition)) { com_err(whoami, stat, amsg); return(stat); }
110 #define ASSERT2(condition,stat,amsg,arg1) \
111     if (!(condition)) { com_err(whoami, stat, amsg, arg1); return(stat); }
112 #define NONNULL(str) \
113     (((str) != (char *)NULL) && (strlen(str) != 0))
114
115     char *service_address, *service_updated, *pathname;
116     int on;
117     
118     /* some sanity checking of arguments while we build data */
119     ASSERT(NONNULL(machine), SMS_INTERNAL, " null host name");
120     ASSERT(NONNULL(service), SMS_INTERNAL, " null service name");
121     ASSERT((strlen(machine) + strlen(service) + 2 < BUFSIZ), SMS_ARG_TOO_LONG,
122            " machine and service names");
123     sprintf(buf, "%s:%s", machine, service);
124     service_updated = strsave(buf);
125     ASSERT(NONNULL(service_updated), SMS_NO_MEM, " for service name");
126     ASSERT((strlen(machine)+strlen(SERVICE_NAME)+2 < BUFSIZ), SMS_ARG_TOO_LONG,
127            " machine and update service name");
128     sprintf(buf, "%s:%s", machine, SERVICE_NAME);
129     service_address = strsave(buf);
130     ASSERT(NONNULL(service_address), SMS_NO_MEM, " for service address");
131     ASSERT(NONNULL(target_path), SMS_INTERNAL, " null target pathname");
132     ASSERT((strlen(target_path) < MAXPATHLEN), SMS_ARG_TOO_LONG,
133            " target pathname");
134     ASSERT2(target_path[0] == '/', SMS_NOT_UNIQUE,
135            " non-absolute pathname supplied \"%s\"", target_path);
136     sprintf(buf, "%s/dcm/%s.out", SMS_DIR, service);
137     pathname = strsave(buf);
138     ASSERT(NONNULL(pathname), SMS_NO_MEM, " for pathname");
139     ASSERT(NONNULL(instructions), SMS_NO_MEM, " for instructions");
140     ASSERT((strlen(instructions) < MAXPATHLEN), SMS_ARG_TOO_LONG,
141            " instruction pathname");
142     
143     initialize();
144     com_err(whoami, 0, "starting update for %s", service_updated);
145     
146     /* open connection */
147     conn = start_server_connection(service_address, 0);
148     if (!conn || (connection_status(conn) == CON_STOPPED)) {
149         com_err(whoami, connection_errno(conn),
150                 " can't connect to update %s", service_address);
151         return(SMS_CANT_CONNECT);
152     }
153     on = 1;
154     setsockopt(conn->in.fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
155     
156     /* send authenticators */
157     code = send_auth(machine);
158     if (code) {
159         com_err(whoami, code, " authorization attempt to %s failed",
160                 service_updated);
161         goto update_failed;
162     }
163     
164     code = send_file(pathname, target_path);
165     if (code)
166       goto update_failed;
167
168     /* send instructions for installation */
169     strcpy(buf, "/tmp/sms-update.XXXXXX");
170     mktemp(buf);
171     code = send_file(instructions, buf);
172     if (code)
173       goto update_failed;
174
175     /* perform installation */
176     code = execute(buf);
177     if (code) {
178         com_err(whoami, code, " installation of %s failed, code = %d",
179                 service_updated, code);
180         goto update_failed;
181     }
182     
183     /* finished updates */
184     code = SMS_SUCCESS;
185
186  update_failed:
187     send_quit();
188     conn = sever_connection(conn);
189     return(code);
190
191 #undef NONNULL
192 #undef ASSERT
193 }
194
195
196 static
197 send_auth(host_name)
198 char *host_name;
199 {
200     KTEXT_ST ticket_st;
201     KTEXT ticket = &ticket_st;
202     STRING data;
203     register int code;
204     int response;
205     
206     code = get_sms_update_ticket(host_name, ticket);
207     if (code) {
208         return(code);
209     }
210     STRING_DATA(data) = "AUTH_001";
211     MAX_STRING_SIZE(data) = 9;
212     code = send_object(conn, (char *)&data, STRING_T);
213     if (code) {
214         return(connection_errno(conn));
215     }
216     code = receive_object(conn, (char *)&response, INTEGER_T);
217     if (code) {
218         return(connection_errno(conn));
219     }
220     if (response) {
221         return(response);
222     }
223     STRING_DATA(data) = (char *)ticket->dat;
224     MAX_STRING_SIZE(data) = ticket->length;
225     code = send_object(conn, (char *)&data, STRING_T);
226     if (code) {
227         return(connection_errno(conn));
228     }
229     code = receive_object(conn, (char *)&response, INTEGER_T);
230     if (code) {
231         return(connection_errno(conn));
232     }
233     if (response) {
234         return(response);
235     }
236     return(SMS_SUCCESS);
237 }
238
239 static
240 execute(path)
241     char *path;
242 {
243     int response;
244     STRING data;
245     register int code;
246     
247     string_alloc(&data, BUFSIZ);
248     sprintf(STRING_DATA(data), "EXEC_002 %s", path);
249     code = send_object(conn, (char *)&data, STRING_T);
250     if (code)
251         return(connection_errno(conn));
252     code = receive_object(conn, (char *)&response, INTEGER_T);
253     if (code)
254         return(connection_errno(conn));
255     if (dbg & DBG_TRACE)
256       com_err(whoami, response, "execute returned %d", response);
257     if (response)
258       return(response);
259     return(SMS_SUCCESS);
260 }
261
262 send_quit()
263 {
264     STRING str;
265     if (!conn)
266         return;
267     string_alloc(&str, 5);
268     (void) strcpy(STRING_DATA(str), "quit");
269     (void) send_object(conn, (char *)&str, STRING_T);
270     string_free(&str);
271 }
This page took 0.079117 seconds and 5 git commands to generate.