]> andersk Git - moira.git/blob - update/client.c
set keepalives
[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 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
41 extern char *malloc();
42 extern int errno, dbg;
43
44 static char buf[BUFSIZ];
45 static int code;
46
47 CONNECTION 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  */
65 static void
66 initialize()
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
102 int
103 mr_update_server(service, machine, target_path, instructions)
104 char *service;
105 char *machine;
106 char *target_path;
107 char *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
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_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
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(MR_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.05573 seconds and 5 git commands to generate.