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