]> andersk Git - moira.git/blob - update/client.c
pass the mode to get_file
[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     conn = start_server_connection(service_address, "");
149     if (!conn || (connection_status(conn) == CON_STOPPED)) {
150         com_err(whoami, connection_errno(conn),
151                 " can't connect to update %s", service_address);
152         return(MR_CANT_CONNECT);
153     }
154     on = 1;
155     setsockopt(conn->in.fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
156     
157     /* send authenticators */
158     code = send_auth(machine);
159     if (code) {
160         com_err(whoami, code, " authorization attempt to %s failed",
161                 service_updated);
162         goto update_failed;
163     }
164     
165     code = send_file(pathname, target_path);
166     if (code)
167       goto update_failed;
168
169     /* send instructions for installation */
170     strcpy(buf, "/tmp/moira-update.XXXXXX");
171     mktemp(buf);
172     code = send_file(instructions, buf);
173     if (code)
174       goto update_failed;
175
176     /* perform installation */
177     code = execute(buf);
178     if (code) {
179         com_err(whoami, code, " installation of %s failed, code = %d",
180                 service_updated, code);
181         goto update_failed;
182     }
183     
184     /* finished updates */
185     code = MR_SUCCESS;
186
187  update_failed:
188     send_quit();
189     conn = sever_connection(conn);
190     return(code);
191
192 #undef NONNULL
193 #undef ASSERT
194 }
195
196
197 static
198 send_auth(host_name)
199 char *host_name;
200 {
201     KTEXT_ST ticket_st;
202     KTEXT ticket = &ticket_st;
203     STRING data;
204     register int code;
205     int response;
206     
207     code = get_mr_update_ticket(host_name, ticket);
208     if (code) {
209         return(code);
210     }
211     STRING_DATA(data) = "AUTH_001";
212     MAX_STRING_SIZE(data) = 9;
213     code = send_object(conn, (char *)&data, STRING_T);
214     if (code) {
215         return(connection_errno(conn));
216     }
217     code = receive_object(conn, (char *)&response, INTEGER_T);
218     if (code) {
219         return(connection_errno(conn));
220     }
221     if (response) {
222         return(response);
223     }
224     STRING_DATA(data) = (char *)ticket->dat;
225     MAX_STRING_SIZE(data) = ticket->length;
226     code = send_object(conn, (char *)&data, STRING_T);
227     if (code) {
228         return(connection_errno(conn));
229     }
230     code = receive_object(conn, (char *)&response, INTEGER_T);
231     if (code) {
232         return(connection_errno(conn));
233     }
234     if (response) {
235         return(response);
236     }
237     return(MR_SUCCESS);
238 }
239
240 static
241 execute(path)
242     char *path;
243 {
244     int response;
245     STRING data;
246     register int code;
247     
248     string_alloc(&data, BUFSIZ);
249     sprintf(STRING_DATA(data), "EXEC_002 %s", path);
250     code = send_object(conn, (char *)&data, STRING_T);
251     if (code)
252         return(connection_errno(conn));
253     code = receive_object(conn, (char *)&response, INTEGER_T);
254     if (code)
255         return(connection_errno(conn));
256     if (dbg & DBG_TRACE)
257       com_err(whoami, response, "execute returned %d", response);
258     if (response)
259       return(response);
260     return(MR_SUCCESS);
261 }
262
263 send_quit()
264 {
265     STRING str;
266     if (!conn)
267         return;
268     string_alloc(&str, 5);
269     (void) strcpy(STRING_DATA(str), "quit");
270     (void) send_object(conn, (char *)&str, STRING_T);
271     string_free(&str);
272 }
This page took 2.936639 seconds and 5 git commands to generate.