]> andersk Git - moira.git/blob - update/client.c
Major re-write to cleanup & handle new DCM features. Same functionality,
[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;
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 and SMSU error table.
57  * PROBLEMS:
58  *
59  */
60 static void
61 initialize()
62 {
63     static int initialized = 0;
64
65     if (!initialized) {
66         gdb_init();
67         init_smsU_err_tbl();
68         initialized++;
69     }
70 }
71
72
73 /*
74  * FUNCTION:
75  *      sms_update_server(service, machine, target_path)
76  * DESCRIPTION:
77  *      Attempts to perform an update to the named machine
78  *      of the named service.  The file SMS_DIR/dcm/service.out
79  *      will be sent, then the file SMS_DIR/bin/service.sh,
80  *      the the shell script will be executed.
81  * INPUT:
82  *      service
83  *              Name of service to be updated; used to find
84  *              the source data file in the SMS data directory.
85  *      machine
86  *      target_path
87  *              Location to install the file.
88  * RETURN VALUE:
89  *      int:
90  *              Error code, or zero if no error was detected
91  *              in the data supplied to this routine.
92  * SIDE EFFECTS:
93  *      May write information to logs.
94  * PROBLEMS:
95  *
96  */
97
98 int
99 sms_update_server(service, machine, target_path, instructions)
100 char *service;
101 char *machine;
102 char *target_path;
103 char *instructions;
104 {
105 #define ASSERT(condition,stat,amsg) \
106     if (!(condition)) { com_err(whoami, stat, amsg); return(stat); }
107 #define ASSERT2(condition,stat,amsg,arg1) \
108     if (!(condition)) { com_err(whoami, stat, amsg, arg1); return(stat); }
109 #define NONNULL(str) \
110     (((str) != (char *)NULL) && (strlen(str) != 0))
111
112     char *service_address, *service_updated, *pathname;
113     
114     /* some sanity checking of arguments while we build data */
115     ASSERT(NONNULL(machine), SMS_INTERNAL, " null host name");
116     ASSERT(NONNULL(service), SMS_INTERNAL, " null service name");
117     ASSERT((strlen(machine) + strlen(service) + 2 < BUFSIZ), SMS_ARG_TOO_LONG,
118            " machine and service names");
119     sprintf(buf, "%s:%s", machine, service);
120     service_updated = strsave(buf);
121     ASSERT(NONNULL(service_updated), SMS_NO_MEM, " for service name");
122     ASSERT((strlen(machine)+strlen(SERVICE_NAME)+2 < BUFSIZ), SMS_ARG_TOO_LONG,
123            " machine and update service name");
124     sprintf(buf, "%s:%s", machine, SERVICE_NAME);
125     service_address = strsave(buf);
126     ASSERT(NONNULL(service_address), SMS_NO_MEM, " for service address");
127     ASSERT(NONNULL(target_path), SMS_INTERNAL, " null target pathname");
128     ASSERT((strlen(target_path) < MAXPATHLEN), SMS_ARG_TOO_LONG,
129            " target pathname");
130     ASSERT2(target_path[0] == '/', SMS_NOT_UNIQUE,
131            " non-absolute pathname supplied \"%s\"", target_path);
132     sprintf(buf, "%s/dcm/%s.out", SMS_DIR, service);
133     pathname = strsave(buf);
134     ASSERT(NONNULL(pathname), SMS_NO_MEM, " for pathname");
135     ASSERT(NONNULL(instructions), SMS_NO_MEM, " for instructions");
136     ASSERT((strlen(instructions) < MAXPATHLEN), SMS_ARG_TOO_LONG,
137            " instruction pathname");
138     
139     initialize();
140     com_err(whoami, 0, "starting update for %s", service_updated);
141     
142     /* open connection */
143     conn = start_server_connection(service_address, 0);
144     if (!conn || (connection_status(conn) == CON_STOPPED)) {
145         com_err(whoami, connection_errno(conn),
146                 " can't connect to update %s", service_address);
147         return(SMS_CANT_CONNECT);
148     }
149     
150     /* send authenticators */
151     code = send_auth(machine);
152     if (code) {
153         com_err(whoami, code, " authorization attempt to %s failed",
154                 service_updated);
155         goto update_failed;
156     }
157     
158     code = send_file(pathname, target_path);
159     if (code)
160       goto update_failed;
161
162     /* send instructions for installation */
163     strcpy(buf, "/tmp/sms-update.XXXXXX");
164     mktemp(buf);
165     code = send_file(instructions, buf);
166     if (code)
167       goto update_failed;
168
169     /* perform installation */
170     code = execute(buf);
171     if (code) {
172         com_err(whoami, code, " installation of %s failed, code = %d",
173                 service_updated, code);
174         goto update_failed;
175     }
176     
177     /* finished updates */
178     code = SMS_SUCCESS;
179
180  update_failed:
181     send_quit();
182     conn = sever_connection(conn);
183     return(code);
184
185 #undef NONNULL
186 #undef ASSERT
187 }
188
189
190 static
191 send_auth(host_name)
192 char *host_name;
193 {
194     KTEXT_ST ticket_st;
195     KTEXT ticket = &ticket_st;
196     STRING data;
197     register int code;
198     int response;
199     
200     code = get_sms_update_ticket(host_name, ticket);
201     if (code) {
202         return(code);
203     }
204     STRING_DATA(data) = "AUTH_001";
205     MAX_STRING_SIZE(data) = 9;
206     code = send_object(conn, (char *)&data, STRING_T);
207     if (code) {
208         return(connection_errno(conn));
209     }
210     code = receive_object(conn, (char *)&response, INTEGER_T);
211     if (code) {
212         return(connection_errno(conn));
213     }
214     if (response) {
215         return(response);
216     }
217     STRING_DATA(data) = (char *)ticket->dat;
218     MAX_STRING_SIZE(data) = ticket->length;
219     code = send_object(conn, (char *)&data, STRING_T);
220     if (code) {
221         return(connection_errno(conn));
222     }
223     code = receive_object(conn, (char *)&response, INTEGER_T);
224     if (code) {
225         return(connection_errno(conn));
226     }
227     if (response) {
228         return(response);
229     }
230     return(SMS_SUCCESS);
231 }
232
233 static
234 execute(path)
235     char *path;
236 {
237     union wait response;
238     STRING data;
239     register int code;
240     
241     string_alloc(&data, BUFSIZ);
242     sprintf(STRING_DATA(data), "EXEC_002 %s", path);
243     code = send_object(conn, (char *)&data, STRING_T);
244     if (code)
245         return(connection_errno(conn));
246     code = receive_object(conn, (char *)&response, INTEGER_T);
247     if (code)
248         return(connection_errno(conn));
249     if (response.w_retcode) {
250 /****************************************************************
251  * The following line is there because the current update servers
252  * don't return the correct error code when an update fails.  Remove
253  * this line when they are fixed.  -mar  7/26/88
254  ****************************************************************/
255         return(SMS_INTERNAL);
256         return(response.w_retcode);
257     }
258     return(SMS_SUCCESS);
259 }
260
261 send_quit()
262 {
263     STRING str;
264     if (!conn)
265         return;
266     string_alloc(&str, 5);
267     (void) strcpy(STRING_DATA(str), "quit");
268     (void) send_object(conn, (char *)&str, STRING_T);
269     string_free(&str);
270 }
This page took 0.049462 seconds and 5 git commands to generate.