]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/zwgc/zephyr.c
9ad8dbe4aabc78bc2c72c5114e6ccfa8845f5860
[1ts-debian.git] / zephyr / zwgc / zephyr.c
1 /* This file is part of the Project Athena Zephyr Notification System.
2  * It is one of the source files comprising zwgc, the Zephyr WindowGram
3  * client.
4  *
5  *      Created by:     Marc Horowitz <marc@athena.mit.edu>
6  *
7  *      $Id$
8  *
9  *      Copyright (c) 1989 by the Massachusetts Institute of Technology.
10  *      For copying and distribution information, see the file
11  *      "mit-copyright.h".
12  */
13
14 #include <sysdep.h>
15
16 #if (!defined(lint) && !defined(SABER))
17 static const char rcsid_zephyr_c[] = "$Id$";
18 #endif
19
20 #include <zephyr/mit-copyright.h>
21
22 /****************************************************************************/
23 /*                                                                          */
24 /*               Module containing code dealing with zephyr:                */
25 /*                                                                          */
26 /****************************************************************************/
27
28 #include <zephyr/zephyr.h>
29 #include <sys/socket.h>
30 #include "new_string.h"
31 #include "zephyr.h"
32 #include "error.h"
33 #include "mux.h"
34 #include "subscriptions.h"
35 #include "variables.h"
36 #include "pointer.h"
37 #include "main.h"
38 #ifndef X_DISPLAY_MISSING
39 #include "X_driver.h"
40 #endif
41
42 #ifdef DEBUG
43 extern int zwgc_debug;
44 #endif /* DEBUG */
45
46 static int zephyr_inited = 0;
47 static unsigned short zephyr_port = 0;
48     
49 /*
50  *  Internal Routine:
51  *
52  *    string get_zwgc_port_number_filename()
53  *        Effects: Returns the filename that the zwgc port # is/should be
54  *                 stored in, based on the user's uid & the environment
55  *                 variable WGFILE.  The returned string points into a
56  *                 static buffer that may change on further calls to this
57  *                 routine or getenv.  The returned string should not be
58  *                 modified in any way.
59  */
60
61 static string get_zwgc_port_number_filename()
62 {
63     static char buffer[40];
64     char *temp;
65     char *getenv();
66
67     if (temp = getenv("WGFILE"))
68       return(temp);
69     else {
70         sprintf(buffer, "/tmp/wg.%d", getuid());
71         return(buffer);
72     }
73 }
74
75 /*
76  *  Write out the port number to the wg file.
77  */
78
79 void write_wgfile()
80 {
81     char *name = get_zwgc_port_number_filename();
82     FILE *port_file;
83
84     port_file = fopen(name, "w");
85     if (port_file) {
86         fprintf(port_file, "%d\n", zephyr_port);
87         fclose(port_file);
88     } else {
89         fprintf(stderr, "zwgc: error while opening %s for writing: ", name);
90         perror("");
91     }
92 }
93
94 /*
95  *
96  */
97
98 static void handle_zephyr_input(notice_handler)
99      void (*notice_handler)();
100 {
101     ZNotice_t *notice;
102     struct sockaddr_in from;
103     int complete_packets_ready;
104
105     for (;;) {
106         errno = 0;
107         if ( (complete_packets_ready=ZPending()) < 0 )
108           FATAL_TRAP( errno, "while calling ZPending()" );
109     
110         if (complete_packets_ready==0)
111           return;
112
113         notice = malloc(sizeof(ZNotice_t));
114
115         TRAP( ZReceiveNotice(notice, &from), "while getting zephyr notice" );
116         if (!error_code) {
117             notice->z_auth = ZCheckAuthentication(notice, &from);
118             notice_handler(notice);
119         }
120     }
121 }
122
123 /*
124  *
125  */
126
127 void zephyr_init(notice_handler)
128      void (*notice_handler)();
129 {
130     char *temp;
131     char *exposure;
132     char *tty = NULL;
133     FILE *port_file;
134
135     /*
136      * Initialize zephyr.  If error, print error message & exit.
137      */
138     FATAL_TRAP( ZInitialize(), "while initializing Zephyr" );
139     FATAL_TRAP( ZOpenPort(&zephyr_port), "while opening Zephyr port" );
140
141     /*
142      * Save away our port number in a special place so that zctl and
143      * other clients can send us control messages: <<<>>>
144      */
145     temp = get_zwgc_port_number_filename();
146     port_file = fopen(temp, "r");
147     if (port_file) {
148         fprintf(stderr, "zwgc: windowgram file already exists.  If you are\n");
149         fprintf(stderr, "zwgc: not already running zwgc, delete %s\n", temp);
150         fprintf(stderr, "zwgc: and try again.\n");
151         exit(1);
152     }
153     write_wgfile();
154
155     /* Set hostname and tty for locations.  If we support X, use the
156      * display string for the default tty name. */
157     if (location_override)
158         tty = location_override;
159 #ifndef X_DISPLAY_MISSING
160     else if (dpy)
161         tty = DisplayString(dpy);
162 #endif
163     error_code = ZInitLocationInfo(NULL, tty);
164     TRAP( error_code, "while initializing location information" );
165
166     /*
167      * Retrieve the user's desired exposure level (from the zephyr variable
168      * "exposure"), convert it to the proper internal form then 
169      * set the user's location using it.  If the exposure level is
170      * not one of the allowed ones, print an error and treat it as
171      * EXPOSE_NONE.
172      */
173     if (temp = ZGetVariable("exposure")) {
174         if (!(exposure = ZParseExposureLevel(temp))) {
175             ERROR2("invalid exposure level %s, using exposure level none instead.\n", temp);
176             exposure = EXPOSE_NONE;
177         }
178     } else
179       exposure = EXPOSE_OPSTAFF;
180     error_code = ZSetLocation(exposure); /* <<<>>> */
181     if (error_code != ZERR_LOGINFAIL)
182       TRAP( error_code, "while setting location" );
183
184     /*
185      * If the exposure level isn't EXPOSE_NONE, turn on recieving notices.
186      * (this involves reading in the subscription file, etc.)
187      */
188     if (string_Neq(exposure, EXPOSE_NONE))
189       zwgc_startup();
190
191     /*
192      * Set $realm to our realm and $user to our zephyr username:
193      */
194     var_set_variable("realm", ZGetRealm());
195     var_set_variable("user", ZGetSender());
196
197     /*
198      * <<<>>>
199      */
200     mux_add_input_source(ZGetFD(), (void (*)())handle_zephyr_input,
201                          notice_handler);
202     zephyr_inited = 1;
203     return;
204 }
205
206 /*
207  *
208  */
209
210 void finalize_zephyr() /* <<<>>> */
211 {
212     string temp;
213
214     if (zephyr_inited) {
215         /*
216          * Remove the file containing our port # since it is no longer needed:
217          */
218         errno = 0;
219         temp = get_zwgc_port_number_filename();
220         unlink(temp);
221         if (errno) {
222             fprintf(stderr, "zwgc: error while trying to delete %s: ", temp);
223             perror("");
224         }
225
226         /*
227          * Cancel our subscriptions, unset our location, and close our zephyr
228          * connection:
229          */
230 #ifdef DEBUG
231         if (zwgc_debug) {
232             TRAP( ZUnsetLocation(), "while unsetting location" );
233             TRAP( ZCancelSubscriptions(0), "while canceling subscriptions" );
234         } else {
235 #endif /* DEBUG */
236             (void) ZUnsetLocation();
237             (void) ZCancelSubscriptions(0);
238 #ifdef DEBUG
239         }
240 #endif /* DEBUG */
241         ZClosePort();
242     }
243     return;
244 }