]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * $Source$ | |
3 | * $Author$ | |
4 | * $Header$ | |
5 | * | |
6 | * Copyright (C) 1987, 1989, 1990 by the Massachusetts Institute of | |
7 | * Technology | |
8 | * For copying and distribution information, please see the file | |
9 | * <mit-copyright.h>. | |
10 | * | |
11 | * This routine is part of the client library. It handles | |
12 | * the protocol operations: invoking an update and getting the | |
13 | * MR message of the day. | |
14 | */ | |
15 | ||
16 | #ifndef lint | |
17 | static char *rcsid_sms_do_update_c = "$Header$"; | |
18 | #endif lint | |
19 | ||
20 | #include <mit-copyright.h> | |
21 | #include <strings.h> | |
22 | #include "mr_private.h" | |
23 | ||
24 | ||
25 | /* Invoke a DCM update. */ | |
26 | ||
27 | int mr_do_update() | |
28 | { | |
29 | int status; | |
30 | mr_params param_st; | |
31 | struct mr_params *params = NULL; | |
32 | struct mr_params *reply = NULL; | |
33 | ||
34 | CHECK_CONNECTED; | |
35 | params = ¶m_st; | |
36 | params->mr_version_no = sending_version_no; | |
37 | params->mr_procno = MR_DO_UPDATE; | |
38 | params->mr_argc = 0; | |
39 | params->mr_argl = NULL; | |
40 | params->mr_argv = NULL; | |
41 | ||
42 | if ((status = mr_do_call(params, &reply)) == 0) | |
43 | status = reply->mr_status; | |
44 | ||
45 | mr_destroy_reply(reply); | |
46 | ||
47 | return status; | |
48 | } | |
49 | ||
50 | ||
51 | /* Get the MR motd. This returns an MR status, and motd will either | |
52 | * point to NULL or the motd in a static buffer. | |
53 | */ | |
54 | ||
55 | int mr_motd(motd) | |
56 | char **motd; | |
57 | { | |
58 | int status; | |
59 | mr_params param_st; | |
60 | struct mr_params *params = NULL; | |
61 | struct mr_params *reply = NULL; | |
62 | static char buffer[1024]; | |
63 | ||
64 | *motd = NULL; | |
65 | CHECK_CONNECTED; | |
66 | params = ¶m_st; | |
67 | params->mr_version_no = sending_version_no; | |
68 | params->mr_procno = MR_MOTD; | |
69 | params->mr_argc = 0; | |
70 | params->mr_argl = NULL; | |
71 | params->mr_argv = NULL; | |
72 | ||
73 | if ((status = mr_do_call(params, &reply))) | |
74 | goto punt; | |
75 | ||
76 | while ((status = reply->mr_status) == MR_MORE_DATA) { | |
77 | if (reply->mr_argc > 0) { | |
78 | strncpy(buffer, reply->mr_argv[0], sizeof(buffer)); | |
79 | *motd = buffer; | |
80 | } | |
81 | mr_destroy_reply(reply); | |
82 | reply = NULL; | |
83 | ||
84 | initialize_operation(_mr_recv_op, mr_start_recv, &reply, | |
85 | (int (*)())NULL); | |
86 | queue_operation(_mr_conn, CON_INPUT, _mr_recv_op); | |
87 | ||
88 | mr_complete_operation(_mr_recv_op); | |
89 | if (OP_STATUS(_mr_recv_op) != OP_COMPLETE) { | |
90 | mr_disconnect(); | |
91 | status = MR_ABORTED; | |
92 | return(status); | |
93 | } | |
94 | } | |
95 | punt: | |
96 | mr_destroy_reply(reply); | |
97 | /* for backwards compatability */ | |
98 | if (status == MR_UNKNOWN_PROC) | |
99 | return(0); | |
100 | else | |
101 | return(status); | |
102 | } | |
103 | ||
104 | ||
105 | /* Tell the library to take care of another input source while it is | |
106 | * processing a query. For instance, an X toolkit application would | |
107 | * do something like | |
108 | * mr_set_alternate_input(ConnectionNumber(XtDisplay(widget)), doxinput); | |
109 | * where doxinput is defined as: | |
110 | * doxinput() { | |
111 | * extern Widget toplevel; | |
112 | * XEvent event; | |
113 | * while (XPending(XtDisplay(toplevel))) { | |
114 | * XNextEvent(XtDisplay(toplevel), &event); | |
115 | * XtDispatchEvent(&event); | |
116 | * } | |
117 | * XFlush(XtDisplay(toplevel)); | |
118 | * } | |
119 | */ | |
120 | ||
121 | static int mr_alternate_input = 0; | |
122 | static int (*mr_alternate_handler)(); | |
123 | ||
124 | int mr_set_alternate_input(fd, proc) | |
125 | int fd; | |
126 | int (*proc)(); | |
127 | { | |
128 | if (mr_alternate_input != 0) | |
129 | return(MR_ALREADY_CONNECTED); | |
130 | mr_alternate_input = fd; | |
131 | mr_alternate_handler = proc; | |
132 | return(MR_SUCCESS); | |
133 | } | |
134 | ||
135 | ||
136 | /* This is used by the parts of the library that must wait for GDB. It | |
137 | * handles alternate input streams (such as X) as well. | |
138 | */ | |
139 | ||
140 | mr_complete_operation(op) | |
141 | OPERATION op; | |
142 | { | |
143 | long infd, outfd, exfd; | |
144 | int rc; | |
145 | ||
146 | gdb_progress(); /* try for an immediate completion */ | |
147 | ||
148 | if (mr_alternate_input == 0) | |
149 | return(complete_operation(op)); | |
150 | ||
151 | infd = (1<<mr_alternate_input); | |
152 | outfd = exfd = 0; | |
153 | ||
154 | while(op->status != OP_COMPLETE && op->status != OP_CANCELLED) { | |
155 | rc = con_select(mr_alternate_input, (fd_set *)&infd, (fd_set *)&outfd, | |
156 | (fd_set *)&exfd, (struct timeval *)NULL); | |
157 | if (rc > 0 && mr_alternate_handler) { | |
158 | (*mr_alternate_handler)(); | |
159 | } | |
160 | } | |
161 | return(op->status); | |
162 | } | |
163 |