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