]> andersk Git - moira.git/blame_incremental - update/client.c
check new hosttable info
[moira.git] / update / client.c
... / ...
CommitLineData
1/*
2 * $Source$
3 * $Header$
4 */
5
6#ifndef lint
7static 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 MOIRA 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 * mr_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 <moira.h>
38#include <moira_site.h>
39#include <krb.h>
40
41extern char *malloc();
42extern int errno, dbg;
43
44static char buf[BUFSIZ];
45static int code;
46
47CONNECTION conn;
48
49
50/*
51 * FUNCTION:
52 * initialize()
53 * DESCRIPTION:
54 * Insures that various libraries have a chance to get
55 * initialized.
56 * INPUT:
57 * OUTPUT:
58 * RETURN VALUE:
59 * void
60 * SIDE EFFECTS:
61 * Initializes GDB library.
62 * PROBLEMS:
63 *
64 */
65static void
66initialize()
67{
68 static int initialized = 0;
69
70 if (!initialized) {
71 gdb_init();
72 initialized++;
73 }
74}
75
76
77/*
78 * FUNCTION:
79 * mr_update_server(service, machine, target_path)
80 * DESCRIPTION:
81 * Attempts to perform an update to the named machine
82 * of the named service. The file DCM_DIR/service.out
83 * will be sent, then the file SMS_DIR/bin/service.sh,
84 * the the shell script will be executed.
85 * INPUT:
86 * service
87 * Name of service to be updated; used to find
88 * the source data file in the MR data directory.
89 * machine
90 * target_path
91 * Location to install the file.
92 * RETURN VALUE:
93 * int:
94 * Error code, or zero if no error was detected
95 * in the data supplied to this routine.
96 * SIDE EFFECTS:
97 * May write information to logs.
98 * PROBLEMS:
99 *
100 */
101
102int
103mr_update_server(service, machine, target_path, instructions)
104char *service;
105char *machine;
106char *target_path;
107char *instructions;
108{
109#define ASSERT(condition,stat,amsg) \
110 if (!(condition)) { com_err(whoami, stat, amsg); return(stat); }
111#define ASSERT2(condition,stat,amsg,arg1) \
112 if (!(condition)) { com_err(whoami, stat, amsg, arg1); return(stat); }
113#define NONNULL(str) \
114 (((str) != (char *)NULL) && (strlen(str) != 0))
115
116 char *service_address, *service_updated, *pathname;
117 int on;
118
119 /* some sanity checking of arguments while we build data */
120 ASSERT(NONNULL(machine), MR_INTERNAL, " null host name");
121 ASSERT(NONNULL(service), MR_INTERNAL, " null service name");
122 ASSERT((strlen(machine) + strlen(service) + 2 < BUFSIZ), MR_ARG_TOO_LONG,
123 " machine and service names");
124 sprintf(buf, "%s:%s", machine, service);
125 service_updated = strsave(buf);
126 ASSERT(NONNULL(service_updated), MR_NO_MEM, " for service name");
127 ASSERT((strlen(machine)+strlen(SERVICE_NAME)+2 < BUFSIZ), MR_ARG_TOO_LONG,
128 " machine and update service name");
129 sprintf(buf, "%s:%s", machine, SERVICE_NAME);
130 service_address = strsave(buf);
131 ASSERT(NONNULL(service_address), MR_NO_MEM, " for service address");
132 ASSERT(NONNULL(target_path), MR_INTERNAL, " null target pathname");
133 ASSERT((strlen(target_path) < MAXPATHLEN), MR_ARG_TOO_LONG,
134 " target pathname");
135 ASSERT2(target_path[0] == '/', MR_NOT_UNIQUE,
136 " non-absolute pathname supplied \"%s\"", target_path);
137 sprintf(buf, "%s/%s.out", DCM_DIR, service);
138 pathname = strsave(buf);
139 ASSERT(NONNULL(pathname), MR_NO_MEM, " for pathname");
140 ASSERT(NONNULL(instructions), MR_NO_MEM, " for instructions");
141 ASSERT((strlen(instructions) < MAXPATHLEN), MR_ARG_TOO_LONG,
142 " instruction pathname");
143
144 initialize();
145 com_err(whoami, 0, "starting update for %s", service_updated);
146
147 /* open connection */
148 gdb_Options |= GDB_OPT_KEEPALIVE;
149 conn = start_server_connection(service_address, "");
150 if (!conn || (connection_status(conn) == CON_STOPPED)) {
151 com_err(whoami, connection_errno(conn),
152 " can't connect to update %s", service_address);
153 return(MR_CANT_CONNECT);
154 }
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, 0);
165 if (code)
166 goto update_failed;
167
168 /* send instructions for installation */
169 strcpy(buf, "/tmp/moira-update.XXXXXX");
170 mktemp(buf);
171 code = send_file(instructions, buf, 0);
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 = MR_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
196static
197send_auth(host_name)
198char *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_mr_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(MR_SUCCESS);
237}
238
239static
240execute(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(MR_SUCCESS);
260}
261
262send_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.046598 seconds and 5 git commands to generate.