dtlogin: Resolve 7 compiler warnings.
[oweals/cde.git] / cde / programs / dtlogin / vgcallback.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $TOG: vgcallback.c /main/16 1998/11/02 18:34:55 mgreess $ */
24 /*                                                                      *
25  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
26  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
27  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
28  * (c) Copyright 1993, 1994 Novell, Inc.                                *
29  */
30 /************************************<+>*************************************
31  ****************************************************************************
32  **
33  **   File:        vgcallback.c
34  **
35  **   Project:     HP Visual User Environment (DT)
36  **
37  **   Description: Callback routines Dtgreet application.
38  **
39  **                These routines handle the callbacks from the widgets.
40  **
41  **
42  **   (c) Copyright 1987, 1988, 1989 by Hewlett-Packard Company
43  **
44  **
45  **
46  ****************************************************************************
47  ************************************<+>*************************************/
48
49
50 /***************************************************************************
51  *
52  *  Includes
53  *
54  ***************************************************************************/
55
56 #include        <stdio.h>
57 #include        <unistd.h>
58 #include        <setjmp.h>
59 #include        <signal.h>
60 #include        <sys/signal.h>
61 #include        <sys/param.h>
62
63 #include        <Xm/Xm.h>
64 #include        <Xm/MessageB.h>
65 #include        <Xm/TextF.h>
66 #include        <Xm/TextFP.h>
67 #include        <Xm/PushBG.h>
68 #include        <Xm/ToggleBG.h>
69 #include    <Dt/IconFile.h>
70 #include    <Dt/Icon.h>
71 #include        <pwd.h>
72
73
74 #ifdef AUDIT
75 #    include <sys/audit.h>
76 #endif
77
78 /* necessary for bzero */
79 #ifdef SVR4
80 #include        <X11/Xfuncs.h>
81 #endif
82
83 #include        "vg.h"
84 #include        "vgmsg.h"
85
86
87 /***************************************************************************
88  *
89  *  External declarations
90  *
91  ***************************************************************************/
92
93 extern  LogoInfo        logoInfo; /* information about the logo            */
94
95
96
97 /***************************************************************************
98  *
99  *  Procedure declarations
100  *
101  ***************************************************************************/
102
103 static void CenterForm( Widget w1, Widget w2);
104 static void PingLost( void ) ;
105 static SIGVAL PingBlocked( int arg ) ;
106 static void ProcessTraversal( Widget w, int direction) ;
107 static void _DtShowDialog(DialogType dtype, XmString msg);
108 static void TellRequester(char * buf, size_t nbytes);
109
110 #  ifdef BLS
111 static  void PromptSensitivityLevel(void); /* prompt for B1 Sen. Level     */
112         int  VerifySensitivityLevel(void); /* verify B1 Sensitivity Level  */
113 #  endif
114
115 static int session_selected = False;
116 static Widget default_dt = NULL;
117
118
119 /***************************************************************************
120  *
121  *  Global variables
122  *
123  ***************************************************************************/
124
125        Widget   focusWidget = NULL;
126
127 char    *userName = "\0";
128 struct passwd *user_p;
129
130
131 #ifdef BLS
132 static  int     normalPasswordWidget = True;
133         char    *sensitivityLevel = NULL;
134 #endif
135
136 #ifndef SVR4
137         long    groups[NGROUPS];
138 #endif
139
140 #ifdef SIA
141   
142 #include <alloca.h>
143
144 SiaFormInfo siaFormInfo;
145
146
147 XmString multiline_xmstring(char *text)
148 {
149
150     char *start, *end;
151     Boolean done;
152     XmString string = NULL;
153     XmString tmp_string;
154     XmString separator = NULL;
155     char *buffer;
156
157     if (!text) return (NULL);
158
159
160     buffer = alloca(strlen((const char *)text) + 1);
161
162     start = text;
163     done = FALSE;
164
165
166     while ( ! done)           /* loop thu local copy */
167       {                               /* looking for \n */
168       end = start;
169
170       while ((*end != '\0') && (*end != '\n'))  end++;
171
172       if (*end == '\0')
173           done = TRUE;                /* we are at the end */
174
175       /* Don't convert empty string unless it's an initial newline. */
176       if ((start != end) || (start == text))
177           {
178           strncpy(buffer, start, end - start);
179           buffer[end - start] = '\0';
180           if (!string)
181               string = XmStringCreate(buffer, XmFONTLIST_DEFAULT_TAG);
182           else
183               {
184               tmp_string = XmStringCreate(buffer, XmFONTLIST_DEFAULT_TAG);
185               string = XmStringConcat(string, tmp_string);
186               XmStringFree(tmp_string);
187               }
188           }
189
190       /* Make a separator if this isn't the last segment. */
191       if (!done) 
192           {
193           if (!separator)
194               separator = XmStringSeparatorCreate();
195           string = XmStringConcat(string, separator);
196           start = ++end;              /* start at next char */
197           }
198       }
199
200     if (separator)
201       XmStringFree(separator);
202
203     return (string);
204 }
205
206 #endif /* SIA */
207
208
209 /***************************************************************************
210  *
211  *  CenterForm
212  *
213  *  Utility function to center one form horizontally within another.
214  ***************************************************************************/
215
216 static void 
217 CenterForm( Widget w1, Widget w2 )
218 {
219
220     Dimension   width;
221     int         i, width1, width2;
222    
223     XtSetArg(argt[0], XmNwidth,  &width);
224     XtGetValues(w1, argt, 1);
225     width1 = (int)width;    
226
227     XtSetArg(argt[0], XmNwidth,  &width);
228     XtGetValues(w2, argt, 1);
229     width2 = (int)width;
230     
231     i = 0;
232     XtSetArg(argt[i], XmNleftAttachment,        XmATTACH_FORM           ); i++;
233     XtSetArg(argt[i], XmNleftOffset,            (width1 - width2) / 2   ); i++;
234     XtSetValues(w2,  argt, i);
235 }
236
237
238
239  
240 /***************************************************************************
241  *
242  *  CleanupAndExit
243  *
244  *  close things down gracefully and exit
245  ***************************************************************************/
246
247 void 
248 CleanupAndExit( Widget w, int exit_code )
249 {
250     int i;
251     Boolean  toggleon;          /* status of session toggle buttons     */
252     
253 #ifdef VG_TRACE
254     vg_TRACE_EXECUTION("main:  entered CleanupAndExit ...");
255 #endif /* VG_TRACE */
256
257     if (w != NULL)
258       XtDestroyWidget(w);
259     
260     /*
261      *  if user is logging in, set type of session desired. No more than
262      *  one session type can be selected at a time (if any) ...
263      */
264
265     if ( exit_code == NOTIFY_OK ) {
266         XtSetArg(argt[0], XmNset,       &toggleon               );
267
268         XtGetValues(options_failsafe, argt, 1);
269         if ( toggleon ) exit_code = NOTIFY_FAILSAFE;
270
271         XtGetValues(options_dtlite, argt, 1);
272         if ( toggleon ) exit_code = NOTIFY_DTLITE;
273
274
275         XtGetValues(options_dt, argt, 1);
276         if ( toggleon ) exit_code = NOTIFY_DT;
277
278
279         if(options_last_dt != NULL) {
280         XtGetValues(options_last_dt, argt, 1);
281         if ( toggleon ) exit_code = NOTIFY_LAST_DT;
282         }
283
284         for(i = 0; i < appInfo.altDts ; ++i) {
285           if(alt_dts[i] != NULL) {
286            XtGetValues(alt_dts[i], argt, 1);
287               if ( toggleon ) exit_code = NOTIFY_ALT_DTS + i + 1; /* alt desktops start  at 1 */ 
288            }    
289
290         }
291
292     }
293
294     if (!session_selected)
295         exit_code = NOTIFY_OK;
296
297     CloseCatalog();
298
299     ChangeBell("on");
300     UnsecureDisplay();
301     XSync (dpyinfo.dpy, 0);
302
303     XtCloseDisplay(dpyinfo.dpy);
304     exit (exit_code);
305 }
306
307
308 /***************************************************************************
309  *
310  *  ClearDtlabel
311  *
312  ***************************************************************************/
313
314 static void
315 ClearDtlabel(void)
316 {
317     int i;
318     XmString xms;
319
320 #ifdef VG_TRACE
321     vg_TRACE_EXECUTION("ClearDtlabel:  entered ...");
322 #endif /* VG_TRACE */
323
324     i = 0;
325     xms = XmStringCreateLocalized("       ");
326     XtSetArg(argt[i], XmNlabelString, xms); i++;
327     XtSetValues(dt_label, argt, i);
328     XmStringFree(xms);
329 }
330
331
332 /***************************************************************************
333  *
334  *  ClearDtlabel
335  *
336  ***************************************************************************/
337
338 static void
339 ClearDtButtons(void)
340 {
341     int i;
342
343     /*
344      *  Clear Dt toggles...
345      */
346     XtSetArg(argt[0], XmNset, False);
347
348     for (i=0; i<appInfo.altDts; ++i)
349       if (alt_dts[i] != NULL)
350         XtSetValues(alt_dts[i], argt, 1);
351
352     if (options_failsafe) XtSetValues(options_failsafe, argt, 1);
353     if (options_dtlite) XtSetValues(options_dtlite, argt, 1);
354     if (options_dt) XtSetValues(options_dt, argt, 1);
355     if (options_last_dt) XtSetValues(options_last_dt, argt, 1);
356 }
357
358
359
360  
361 /***************************************************************************
362  *
363  *  RespondClearCB
364  *
365  *  clear name/password text fields
366  ***************************************************************************/
367
368 void 
369 RespondClearCB( Widget w, XtPointer client, XtPointer call )
370 {
371   char buf[REQUEST_LIM_MAXLEN];
372   ResponseClear *r = (ResponseClear *)buf;
373
374 #ifdef VG_TRACE
375   vg_TRACE_EXECUTION("main:  entered RespondClearCB ...");
376 #endif /* VG_TRACE */
377
378   ClearDtlabel();
379   ClearDtButtons();
380   SetDefaultDt(NULL);
381
382   r->hdr.opcode = REQUEST_OP_CLEAR;
383   r->hdr.reserved = 0;
384   r->hdr.length = sizeof(*r);
385
386   TellRequester(buf, (size_t) r->hdr.length);
387 }
388
389
390  
391 /***************************************************************************
392  *
393  *  CopyrightCB
394  *
395  *  move the highlight back to login or password fields AFTER the copyright
396  *  dialog is unposted.
397  *
398  ***************************************************************************/
399
400 void 
401 CopyrightCB( Widget w, XtPointer client_data, XtPointer call_data )
402 {
403
404 #ifdef VG_TRACE
405     vg_TRACE_EXECUTION("main:  entered CopyrightCB ...");
406 #endif /* VG_TRACE */
407
408     if ( focusWidget != NULL)
409         ProcessTraversal(focusWidget, XmTRAVERSE_CURRENT);
410
411 }
412
413
414
415 /***************************************************************************
416  *
417  *  EditPasswdCB
418  *
419  *  implement no-echo and no-cursor motion of the password
420  ***************************************************************************/
421
422 void 
423 EditPasswdCB(Widget w, XtPointer client, XtPointer call_data)
424 {
425     LoginTextPtr        textdata;
426     XmTextVerifyPtr     cbs = (XmTextVerifyPtr) call_data;
427     int                 i;
428     static char         buffer[MAXPATHLEN];
429     register char       *s, *t;
430
431 #ifdef VG_TRACE
432     vg_TRACE_EXECUTION("main:  entered EditPasswdCB ...");
433     vg_TRACE_EXECUTION(
434             "currInsert=%d newInsert=%d startPos=%d endPos=%d\n",
435             cbs->currInsert,cbs->newInsert,cbs->startPos, cbs->endPos);
436     if (cbs->text->ptr) vg_TRACE_EXECUTION("text->ptr=%s\n", cbs->text->ptr);
437     vg_TRACE_EXECUTION("noechobuf=%s\n", textdata->noechobuf);
438 #endif /* VG_TRACE */
439
440     textdata = GetLoginTextPtr(w);
441     if (NULL == textdata || textdata->bEcho) return;
442     if (cbs->reason == XmCR_MOVING_INSERT_CURSOR) return;
443
444     for (i=0, s=buffer, t=textdata->noechobuf;
445          (*t && i<cbs->startPos);
446          i++, s++, t++)
447       *s = *t;
448
449     if (cbs->text->ptr)
450     {
451         strcpy(s, cbs->text->ptr);
452         s += cbs->text->length;
453     }
454     else
455       *s = '\0';
456
457     if (strlen(textdata->noechobuf) >= cbs->endPos)
458     {
459         t = textdata->noechobuf+cbs->endPos;
460         if (strlen(t))
461           strcpy(s, t);
462     }
463
464     strcpy(textdata->noechobuf, buffer);
465
466     if (cbs->text->ptr)
467       for (i=0, s=cbs->text->ptr; i<cbs->text->length; i++, s++)
468         *s = '*';
469
470 #ifdef VG_TRACE
471     vg_TRACE_EXECUTION("textdata->noechobuf=%s\n", textdata->noechobuf);
472 #endif
473 }
474
475
476 /***************************************************************************
477  *
478  *  FakeFocusIn
479  *
480  *  simulate a FocusIn event to the login_shell in order to turn on
481  *  traversal. There is a bug in the Toolkit that is normally masked by 
482  *  the window manager. Since we have no window manager, we need to simulate
483  *  the FocusIn event it sends to the application.
484  *
485  *  Also force the initial focus to the login_text widget.
486  ***************************************************************************/
487
488 void
489 FakeFocusIn( Widget focus_widget, XtPointer client_data, XEvent *eventprm,
490              Boolean *continue_to_dispatch )
491 {
492    XEvent event;
493    XEvent * eventPtr = &event;
494
495 #ifdef VG_TRACE
496    vg_TRACE_EXECUTION("main:  entered FakeFocusIn ...");
497 #endif /* VG_TRACE */
498
499    /*
500     * set the input focus to the login text widget...
501     */
502     
503    XSetInputFocus( XtDisplay(focus_widget),
504                    XtWindow(focus_widget),
505                    RevertToNone,
506                    CurrentTime);
507
508    /*
509     *  create a synthetic focus-in event. 
510     *
511     *  Note: The above call to XSetInputFocus() was not originally included
512     *        in this routine. A bug fix to Motif made it necessary to add
513     *        the call. The synthetic focus-in event is probably now
514     *        unnecessary but is left in for caution's sake. (12/08/92)
515     */
516     
517    /* focus_widget = login_shell; */
518    
519    eventPtr->type = FocusIn;
520    eventPtr->xfocus.serial = LastKnownRequestProcessed(XtDisplay(focus_widget));
521    eventPtr->xfocus.send_event = True;
522    eventPtr->xfocus.display = XtDisplay(focus_widget);
523    eventPtr->xfocus.window = XtWindow(focus_widget);
524    eventPtr->xfocus.mode = NotifyNormal;
525    eventPtr->xfocus.detail = NotifyAncestor;
526
527    XtDispatchEvent (eventPtr);
528
529    ProcessTraversal(focus_widget, XmTRAVERSE_CURRENT);
530    
531    XtRemoveEventHandler(focus_widget, ExposureMask, FALSE,
532                    FakeFocusIn, NULL);
533 }
534
535 /***************************************************************************
536  *
537  *  LayoutCB
538  *
539  *  do final layout adjustments right before windows are mapped. This is
540  *  necessary because the size of managers (Forms, etc) is not known until
541  *  their window has been created (XtRealize). We want to make adjustments
542  *  before the windows become visible
543  *
544  *  1. squeeze dialog width to fit on screen.
545  *  2. increase dialog height if widgets overlap.
546  *  3. center the main matte horizontally and vertically
547  *  4. position the pushbuttons
548  *  5. position the copyright
549  *
550  ***************************************************************************/
551
552 void
553 LayoutCB( Widget w, XtPointer client_data, XtPointer call_data )
554 {
555     register int        i, j;
556     Dimension   width, height;  /* size values returned by XtGetValues     */
557     Dimension   shadowThickness;/* size values returned by XtGetValues     */
558     Position    x, y;           /* position values returned by XtGetValues */
559     
560     struct {                    /* position, size of widgets (pixels)      */
561     int x, y;
562     int width;
563     int height;
564     }           mw, pw; /* matte, logo, drop shadow, login matte
565                                        and greeting widgets                */
566
567     int         width1, width2; /* general width variable                  */
568     int         height1;        /* general height variable                 */
569     Position    x1, y1;         /* general position variables              */
570     int         offsety;        /* general offset variable                 */
571     int         shadow_offsetx; /* offset for drop shadow (pixels)         */
572     int         shadow_offsety; /* offset for drop shadow (pixels)         */
573     int         spacing;        /* spacing between login & matte bottoms   */
574     
575     Widget      buttons[4];     /* pushbutton widgets                      */
576
577     XtWidgetGeometry  geometry; /* geometry of a widget                    */
578     
579     int         max_width;      /* maximum width  of a set of widgets      */
580     int         origin;         /* horizontal origin for button placement  */
581     int         space;          /* total available space left between buttons */
582     int         overlap;        /* possible widget overlap                 */
583
584 #ifdef VG_TRACE
585     vg_TRACE_EXECUTION("main:  entered LayoutCB ...");
586 #endif /* VG_TRACE */
587
588     /*
589      * - squeeze dialog to fit onto screen (if necessary)
590      */
591     i = 0;
592     XtSetArg(argt[i], XmNwidth,                 &width                  ); i++;
593     XtGetValues(matte, argt, i);
594     mw.width  = ToPixel(matte, XmHORIZONTAL, (int)width  );
595 #define HMARGIN 4 /* min sum horizontal margin of matte */
596     if (mw.width+HMARGIN > dpyinfo.width)
597     {
598       int delta = mw.width + HMARGIN - dpyinfo.width;
599      /*
600       * Matte width greater than screen so shrink matteFrame
601       * and matte1 width to compensate.
602       */
603       i=0;
604       XtSetArg(argt[i], XmNwidth,       &width          ); i++;
605       XtGetValues(matteFrame, argt, i);
606
607       width1 = ToPixel(matteFrame, XmHORIZONTAL, (int)width  );
608       width1 -= delta;
609       width1 = FromPixel(matteFrame, XmHORIZONTAL, width1 );
610
611       i=0;
612       XtSetArg(argt[i], XmNwidth,       width1          ); i++;
613       XtSetValues(matteFrame, argt, i);
614
615       width1 = dpyinfo.width - HMARGIN;
616       mw.width = FromPixel(matte, XmHORIZONTAL, width1 );
617
618       i=0;
619       XtSetArg(argt[i], XmNwidth,       mw.width        ); i++;
620       XtSetValues(matte, argt, i);
621     }
622
623     /*
624      * - Make sure the login widgets don't overlap.
625      */
626     if (login_form) {
627         i = 0;
628         XtSetArg(argt[i], XmNy,                 &y                      ); i++;
629         XtSetArg(argt[i], XmNheight,            &height                 ); i++;
630         XtGetValues(greeting, argt, i);
631
632         i = 0;
633         XtSetArg(argt[i], XmNy,                 &y1                     ); i++;
634         XtGetValues(login_form, argt, i);
635
636         overlap = y + height - y1;
637
638         if (overlap > -10) {
639             i = 0;
640             XtSetArg(argt[i], XmNbottomAttachment, XmATTACH_WIDGET);    i++;
641             XtSetArg(argt[i], XmNbottomWidget,     login_form);         i++;
642             XtSetArg(argt[i], XmNbottomOffset,     10);                 i++;
643             XtSetValues(greeting, argt, i);
644         }
645     }
646  
647
648     /*
649      *  - center the main matte horizontally and vertically...
650      */
651      
652     i = 0;
653     XtSetArg(argt[i], XmNx,                     &x                      ); i++;
654     XtSetArg(argt[i], XmNy,                     &y                      ); i++;
655     XtSetArg(argt[i], XmNwidth,                 &width                  ); i++;
656     XtSetArg(argt[i], XmNheight,                &height                 ); i++;
657     XtSetArg(argt[i], XmNshadowThickness,       &shadowThickness        ); i++;
658     XtGetValues(matte, argt, i);
659
660     mw.width  = ToPixel(matte, XmHORIZONTAL, (int)width  );
661     mw.height = ToPixel(matte, XmVERTICAL,   (int)height );
662
663     mw.x = ( x > 0 ? ToPixel(matte, XmHORIZONTAL, (int) x)
664             : (dpyinfo.width - mw.width)/2 );
665     
666     mw.y = ( y > 0 ? ToPixel(matte, XmVERTICAL, (int) y)
667             : (dpyinfo.height - mw.height)/2 );
668  
669     if ( mw.x < 0 ) mw.x = 0;
670     if ( mw.y < 0 ) mw.y = 0;
671
672     x1 = FromPixel(matte, XmHORIZONTAL, mw.x );
673     y1 = FromPixel(matte, XmVERTICAL,   mw.y );
674
675     i = 0;
676     XtSetArg(argt[i], XmNx,                     x1                      ); i++;
677     XtSetArg(argt[i], XmNy,                     y1                      ); i++;
678     XtSetValues(matte, argt, i);
679
680
681     /*
682      * space the buttons horizontally. Start at the center of the matte
683      * and allow them to grow towards the edges...
684      */
685
686     i = 0;
687     XtSetArg(argt[i], XmNwidth,         &width                          ); i++;
688     XtGetValues(matte1, argt, i);
689
690     max_width = width;
691
692     i = 0;
693     XtSetArg(argt[i], XmNwidth,         &width                          ); i++;
694     XtGetValues(clear_button, argt, i);
695     
696     space = max_width - 4*width;
697     spacing = space/4;
698     
699     if (spacing < 12) spacing = 12;
700
701     i = 0;
702     XtSetArg(argt[i], XmNleftAttachment, XmATTACH_FORM); i++;
703     XtSetArg(argt[i], XmNleftOffset, spacing/2); i++;
704     XtSetValues(ok_button,  argt, i);
705
706     i = 0;
707     XtSetArg(argt[i], XmNleftAttachment,        XmATTACH_WIDGET         ); i++;
708     XtSetArg(argt[i], XmNleftWidget, ok_button); i++;
709     XtSetArg(argt[i], XmNleftOffset, spacing); i++;
710     XtSetValues(clear_button,  argt, i);
711
712     i = 0;
713     XtSetArg(argt[i], XmNleftAttachment,        XmATTACH_WIDGET         ); i++;
714     XtSetArg(argt[i], XmNleftWidget, clear_button); i++;
715     XtSetArg(argt[i], XmNleftOffset, spacing); i++;
716     XtSetValues(options_button,  argt, i);
717     
718     i = 0;
719     XtSetArg(argt[i], XmNleftAttachment,        XmATTACH_WIDGET         ); i++;
720     XtSetArg(argt[i], XmNleftWidget, options_button); i++;
721     XtSetArg(argt[i], XmNleftOffset, spacing); i++;
722     XtSetValues(help_button,  argt, i);
723     
724     /*
725      *  - adjust the copyright vertically to align top with login_matte...
726      */
727
728     if (copyright_msg) {
729         XtQueryGeometry(copyright_msg, NULL, &geometry);
730     
731         i = 0;
732         XtSetArg(argt[i], XmNshadowThickness,   &width                  ); i++;
733         XtGetValues(copyright_msg, argt, i);
734
735         width1 = ToPixel(copyright_msg, XmHORIZONTAL, width);
736         width1 = (dpyinfo.width - (int) geometry.width - 2 * width1)/2;
737
738         x1 = FromPixel(copyright_msg, XmHORIZONTAL, width1);
739         y1 = FromPixel(copyright_msg, XmVERTICAL, mw.y);
740
741         i = 0;
742         XtSetArg(argt[i], XmNdefaultPosition,   False                   ); i++;
743         XtSetArg(argt[i], XmNx,                 x1                      ); i++;
744         XtSetArg(argt[i], XmNy,                 y1                      ); i++;
745         XtSetValues(copyright_msg, argt, i);
746     }
747 }
748
749
750
751
752 /***************************************************************************
753  *
754  *  MenuItemCB
755  *
756  *  callback for options menu items
757  ***************************************************************************/
758
759 void 
760 MenuItemCB( Widget w, XtPointer client_data, XtPointer call_data )
761 {
762         int i;
763         char     *logoFile;
764         char     *logoName;
765         char    *temp_p;
766         char    temp[MAXPATHLEN];
767
768 #ifdef VG_TRACE
769     vg_TRACE_EXECUTION("main:  entered MenuItemCB ...");
770 #endif /* VG_TRACE */
771
772     session_selected = True;
773
774     switch ( (int) client_data) {
775
776     case OB_RESTART_SERVER:
777         CleanupAndExit(NULL, NOTIFY_RESTART);
778         break;
779
780     case OB_NO_WINDOWS:
781         CleanupAndExit(NULL, NOTIFY_NO_WINDOWS);
782         break;
783
784     case OB_COPYRIGHT:
785         _DtShowDialog(copyright, NULL);
786         break;
787
788     case OB_ALT_DTS:
789     case OB_FAILSAFE:
790     case OB_DTLITE:
791     case OB_DT: 
792     case OB_LAST_DT:
793         /*
794          * set the label on the dt_label widget..
795          */ 
796
797         if(w != options_last_dt) {
798           XtSetArg(argt[0], XmNlabelString, &xmstr);
799           XtGetValues(w, argt, 1);
800
801           XtSetArg(argt[0], XmNlabelString, xmstr);
802           XtSetValues(dt_label, argt, 1);
803         }
804         else
805           ClearDtlabel();
806
807         i = 0;
808         XtSetArg(argt[i], XmNuserData,          &logoFile          ); i++;
809         XtGetValues(w, argt, i);
810
811         /* 
812          * remove trailing spaces 
813          */
814         if(strchr(logoFile,' '))
815             temp_p = strtok(logoFile," ");      
816         else
817             temp_p = logoFile;
818  
819         logoName = _DtGetIconFileName(DefaultScreenOfDisplay(dpyinfo.dpy),
820                           temp_p, NULL, NULL, 0);
821  
822         if (logoName == NULL) {
823            LogError( 
824              ReadCatalog(MC_LOG_SET,MC_LOG_NO_LOGOBIT,MC_DEF_LOG_NO_LOGOBIT),
825                              logoFile);
826            logoFile = NULL;
827         }
828         i = 0;
829         XtSetArg(argt[i], XmNimageName, logoName); i++;
830         XtSetValues(logo_pixmap, argt, i);
831
832         /*
833          *  Clear Dt toggles...
834          */
835         ClearDtButtons();
836
837         /* 
838          * set the selected toggle button...
839          */
840         XtSetArg(argt[0], XmNset, True);
841         XtSetValues(w, argt, 1);
842
843         SetDefaultDt(w);
844
845         /*
846          *  return focus to name/password widgets...
847          */
848          
849         if ( focusWidget != NULL)
850             ProcessTraversal(focusWidget, XmTRAVERSE_CURRENT);
851
852         break;
853     }
854
855 }
856
857
858
859
860 /***************************************************************************
861  *
862  *  OptionsUnmapCB
863  *
864  *  callback when options menu unmaps
865  ***************************************************************************/
866
867 void 
868 OptionsUnmapCB( Widget wd, XtPointer client_data, XtPointer call_data )
869 {
870
871     int         i;
872     Dimension   width, height;
873
874     Widget      w;
875     XEvent      event;
876     
877 #ifdef VG_TRACE
878     vg_TRACE_EXECUTION("main:  entered OptionsUnmapCB ...");
879 #endif /* VG_TRACE */
880
881     /*
882      *  simulate an exposure event over the Options pushbutton to make sure
883      *  the pushbutton elevates. (there is a bug in the toolkit where this
884      *  doesn't always happen on some servers)...
885      */
886
887     w = options_button;
888     
889     i = 0;
890     XtSetArg(argt[i], XmNwidth,                 &width                  ); i++;
891     XtSetArg(argt[i], XmNheight,                &height                 ); i++;
892     XtGetValues(w, argt, i);
893
894     event.type                = Expose;
895     event.xexpose.serial      = LastKnownRequestProcessed(XtDisplay(w));
896     event.xexpose.send_event  = True;
897     event.xexpose.display     = XtDisplay(w);
898     event.xexpose.window      = XtWindow(w);
899     event.xexpose.x           = 0;
900     event.xexpose.y           = 0;
901     event.xexpose.width       = 1;   /* one pixel seems to be good enough, */
902     event.xexpose.height      = 1;   /* but time will tell...              */
903 #if 0
904     event.xexpose.width       = ToPixel(matte, XmHORIZONTAL, (int)width  );
905     event.xexpose.height      = ToPixel(matte, XmVERTICAL,   (int)height );
906 #endif
907     event.xexpose.count       = 0;
908    
909     XtDispatchEvent (&event);
910 }
911
912
913  
914 /***************************************************************************
915  *
916  *  PingServerCB
917  *
918  *  Ping the server occasionally with an Xsync to see if it is still there.
919  *  We do this here rather than in dtlogin since dtgreet has the server
920  *  grabbed.
921  *
922  ***************************************************************************/
923
924 static jmp_buf  pingTime;
925 static int      serverDead = FALSE;
926 static int      pingInterval = 0;       /* ping interval (sec.)            */
927 static int      pingTimeout;            /* ping timeout (sec.)             */
928
929 static void 
930 PingLost( void )
931 {
932     serverDead = TRUE;
933     longjmp (pingTime, 1);
934 }
935
936
937 static SIGVAL
938 PingBlocked( int arg )
939
940 {
941     serverDead = TRUE;
942     longjmp (pingTime, 1);
943 }
944
945
946 int 
947 PingServer( void )
948 {
949     int     (*oldError)();
950     SIGVAL  (*oldSig)();
951     int     oldAlarm;
952
953     oldError = XSetIOErrorHandler ((XIOErrorHandler)PingLost);
954     oldAlarm = alarm (0);
955     oldSig = signal (SIGALRM, PingBlocked);
956     alarm (pingTimeout * 60);
957     if (!setjmp (pingTime))
958     {
959         XSync (dpyinfo.dpy, 0);
960     }
961     else
962     {
963         if ( serverDead ) {
964             LogError(ReadCatalog(
965                                  MC_LOG_SET,MC_LOG_DEADSRV,MC_DEF_LOG_DEADSRV),
966                 dpyinfo.name);
967             alarm (0);
968             signal (SIGALRM, SIG_DFL);
969             XSetIOErrorHandler (oldError);
970             return 0;
971         }
972     }
973     alarm (0);
974     signal (SIGALRM, oldSig);
975     alarm (oldAlarm);
976     XSetIOErrorHandler (oldError);
977     return 1;
978 }
979
980
981 void 
982 PingServerCB( XtPointer call_data, XtIntervalId *id )
983 {
984
985     char *t;
986     
987
988     /*
989      *  get ping values from the environment...
990      */
991
992     if ( pingInterval == 0 ) {
993         pingInterval  = ((t = (char *)getenv(PINGINTERVAL)) == NULL ? 0 : atoi(t));
994         pingTimeout   = ((t = (char *)getenv(PINGTIMEOUT))  == NULL ? 0 : atoi(t));
995     }
996
997     
998     /*
999      *  ping the server. If successful, set a timer for the next ping,
1000      *  otherwise cleanup and exit...
1001      */
1002
1003     if ( pingInterval != 0 ) {
1004         if (PingServer())
1005             XtAddTimeOut((unsigned long) pingInterval * 60 * 1000, 
1006                           PingServerCB, NULL);
1007         else
1008             exit(NOTIFY_RESTART);
1009     }
1010 }
1011
1012
1013  
1014 /***************************************************************************
1015  *
1016  *  PostMenuCB
1017  *
1018  *  post the option_button pop-up menu
1019  ***************************************************************************/
1020
1021 void 
1022 PostMenuCB( Widget w, XtPointer client_data, XtPointer call_data )
1023 {
1024
1025     XmAnyCallbackStruct *p;
1026
1027     p = (XmAnyCallbackStruct *) call_data;
1028
1029 #ifdef VG_TRACE
1030     vg_TRACE_EXECUTION("main:  entered PostMenuCB ...");
1031 #endif /* VG_TRACE */
1032
1033     /*
1034      *  make options menus if they don't yet exist...
1035      */
1036
1037     if (options_menu == NULL)
1038         MakeOptionsMenu();
1039
1040
1041     /*
1042      *  post menu...
1043      */
1044
1045     if (p->reason == XmCR_ARM           &&
1046         p->event->type == ButtonPress) {
1047
1048         XmMenuPosition(options_menu, p->event);
1049         XtManageChild(options_menu);
1050     }
1051 }
1052
1053
1054
1055
1056 /***************************************************************************
1057  *
1058  *  ProcessTraversal
1059  *
1060  *  move the input focus
1061  ***************************************************************************/
1062
1063 static void 
1064 ProcessTraversal( Widget w, int direction )
1065 {
1066     int i;
1067
1068 #ifdef VG_TRACE
1069     vg_TRACE_EXECUTION("main:  entered ProcessTraversal ...");
1070 #endif /* VG_TRACE */
1071
1072     i = XmProcessTraversal(w, direction);
1073
1074 #ifndef __hpux
1075     /*
1076      * Versions of Motif other than HP do not support the XmfocusCallback
1077      * on the TextField widget. We simulate it here by manually invoking the
1078      * callback routine...
1079      */
1080
1081     TextFocusCB(w, NULL, NULL);
1082 #endif    
1083 }
1084
1085
1086
1087  
1088 /***************************************************************************
1089  *
1090  *  RefreshEH
1091  *
1092  *  cause the entire screen to refresh via exposure events
1093  ***************************************************************************/
1094
1095 void 
1096 RefreshEH( Widget w, XtPointer client_data, XEvent *event,
1097              Boolean *continue_to_dispatch )
1098 {
1099
1100     Window      cover;
1101     
1102 #ifdef VG_TRACE
1103     vg_TRACE_EXECUTION("main:  entered RefreshEH ...");
1104 #endif /* VG_TRACE */
1105
1106     /*
1107      *  map/unmap a window that covers the entire screen. The resultant
1108      *  exposure events will refresh the screen. Note, the default
1109      *  background pixmap is NONE.
1110      */
1111      
1112     cover = XCreateWindow ( dpyinfo.dpy,                /* display         */
1113                             dpyinfo.root,               /* root window ID  */
1114                             0,                          /* x origin        */
1115                             0,                          /* y origin        */
1116                             dpyinfo.width,              /* width           */
1117                             dpyinfo.height,             /* height          */
1118                             0,                          /* border width    */
1119                             0,                          /* depth           */
1120                             InputOutput,                /* class           */
1121                             CopyFromParent,             /* visual          */
1122                             0,                          /* value mask      */
1123                             (XSetWindowAttributes *)NULL); /* attributes   */
1124     
1125     XMapWindow(dpyinfo.dpy, cover);
1126     XDestroyWindow(dpyinfo.dpy, cover);
1127     XFlush(dpyinfo.dpy);
1128 }
1129
1130
1131 /***************************************************************************
1132  *
1133  *  RequestCB
1134  *
1135  *  Accept a request from client
1136  ***************************************************************************/
1137
1138 void 
1139 RequestCB(
1140         XtPointer client_data,
1141         int *source,
1142         XtInputId *id)
1143 {
1144   char buf[512];
1145   int count;
1146   int remainder;
1147   RequestHeader *phdr = (RequestHeader *)buf;
1148
1149 #ifdef VG_TRACE
1150   vg_TRACE_EXECUTION("main:  entered RequestCB ...");
1151 #endif /* VG_TRACE */
1152
1153  /*
1154   * There's a request in the pipe. Read the header.
1155   */
1156   count = read(0, buf, sizeof(*phdr));
1157   if (count != sizeof(*phdr))
1158   {
1159     return;
1160   }
1161
1162  /*
1163   * Calculate amount of data after header.
1164   */ 
1165   remainder =  phdr->length - sizeof(*phdr);
1166   if (remainder > 0)
1167   {
1168    /*
1169     * Read remainder of request.
1170     */
1171     count = read(0, buf+sizeof(*phdr), remainder);
1172   }
1173
1174  /* 
1175   * Initiate response to request.
1176   */
1177   switch(phdr->opcode)
1178   {
1179     case REQUEST_OP_EXIT:
1180 #ifdef VG_TRACE
1181       vg_TRACE_EXECUTION("main:  got REQUEST_OP_EXIT ...");
1182 #endif /* VG_TRACE */
1183       RespondExitCB(NULL, NULL, NULL);
1184       break;
1185
1186     case REQUEST_OP_MESSAGE:
1187       {
1188         RequestMessage *r = (RequestMessage *)phdr;
1189         XmString string;
1190
1191 #ifdef VG_TRACE
1192         vg_TRACE_EXECUTION("main:  got REQUEST_OP_MESSAGE ...");
1193 #endif /* VG_TRACE */
1194         if (r->idMC)
1195         {
1196           FILE *fp;
1197
1198          /*
1199           * Caller passed in MC_* message id.
1200           */
1201           if (r->idMC == MC_NO_LOGIN &&
1202               (fp = fopen(NO_LOGIN_FILE,"r")) != NULL)
1203           {
1204            /*
1205             * For MC_NO_LOGIN read message from file.
1206             */
1207             char buffer[256];
1208             int j;
1209
1210             string = NULL;
1211
1212             while (fgets(buffer, 256, fp) != NULL)
1213             {
1214               j = strlen(buffer);
1215               if ( buffer[j-1] == '\n' ) buffer[j-1] = '\0';
1216
1217               string = XmStringConcat(xmstr,
1218                                       XmStringCreate(buffer,
1219                                       XmFONTLIST_DEFAULT_TAG));
1220               string = XmStringConcat(xmstr, XmStringSeparatorCreate());
1221             }
1222           }
1223           else
1224           {
1225            /*
1226             * Read message from message catalog.
1227             */
1228             string = ReadCatalogXms(MC_ERROR_SET, r->idMC, buf+r->offMessage);
1229           }
1230         }
1231         else
1232         {
1233          /*
1234           * Generate message from provided string. 
1235           */
1236 #ifdef SIA
1237           string = multiline_xmstring(buf+r->offMessage);
1238 #else
1239           string = XmStringCreate(buf+r->offMessage,XmFONTLIST_DEFAULT_TAG);
1240 #endif
1241         }
1242       
1243         _DtShowDialog(error, string);
1244  
1245         XmStringFree(string);
1246       }
1247       break;
1248
1249     case REQUEST_OP_HOSTNAME:
1250 #ifdef VG_TRACE
1251       vg_TRACE_EXECUTION("main:  got REQUEST_OP_HOSTNAME ...");
1252 #endif /* VG_TRACE */
1253       _DtShowDialog(hostname, NULL);
1254       break;
1255
1256     case REQUEST_OP_EXPASSWORD:
1257 #ifdef VG_TRACE
1258       vg_TRACE_EXECUTION("main:  got REQUEST_OP_EXPASSWORD ...");
1259 #endif /* VG_TRACE */
1260       _DtShowDialog(expassword, NULL);
1261       break;
1262
1263     case REQUEST_OP_CHPASS:
1264 #ifdef VG_TRACE
1265       vg_TRACE_EXECUTION("main:  got REQUEST_OP_CHPASS ...");
1266 #endif /* VG_TRACE */
1267       break;
1268
1269     case REQUEST_OP_CHALLENGE:
1270       {
1271         RequestChallenge *r = (RequestChallenge *)phdr;
1272         XmString string;
1273         int i;
1274         LoginTextPtr textdata;
1275         Boolean change;
1276
1277 #ifdef VG_TRACE
1278         vg_TRACE_EXECUTION("main:  got REQUEST_OP_CHALLENGE ...");
1279 #endif /* VG_TRACE */
1280         textdata = GetLoginTextPtr(login_text);
1281
1282         change = (textdata->bEcho != r->bEcho);
1283
1284         XtUnmapWidget(textdata->text[textdata->bEcho]);
1285
1286         textdata->bEcho = r->bEcho;
1287         textdata->noechobuf[0] = '\0';
1288
1289         XtAddEventHandler(textdata->text[textdata->bEcho], ExposureMask, False,
1290                         FakeFocusIn, NULL);
1291
1292         XtMapWidget(textdata->text[textdata->bEcho]);
1293
1294         XtPopup(login_shell, XtGrabNone); 
1295
1296         XGrabKeyboard (dpyinfo.dpy, XtWindow (textdata->text[textdata->bEcho]),
1297         False, GrabModeAsync, GrabModeAsync, CurrentTime); 
1298
1299         XmTextFieldSetString(
1300           textdata->text[textdata->bEcho],
1301           r->offUserNameSeed ? buf+r->offUserNameSeed : "");
1302
1303         XmTextFieldSetSelection (
1304           textdata->text[1],
1305           0, XmTextFieldGetLastPosition(textdata->text[1]),
1306           CurrentTime );
1307
1308         if (r->idMC)
1309         {
1310          /*
1311           * Read message from message catalog.
1312           */
1313           string = ReadCatalogXms(MC_LABEL_SET, r->idMC, buf+r->offChallenge);
1314         }
1315         else
1316         {
1317          /*
1318           * Generate message from provided string.
1319           */
1320           string = XmStringCreate(buf+r->offChallenge,XmFONTLIST_DEFAULT_TAG);
1321         }
1322
1323         i = 0;
1324         XtSetArg(argt[i], XmNlabelString,       string                   ); i++;
1325         XtSetValues(login_label, argt, i);
1326
1327         XmStringFree(string); 
1328
1329         if (change)
1330         {
1331            char buf[256];
1332
1333            i = 0;
1334            if (textdata->bEcho)
1335            {
1336              XtSetArg(argt[i], XmNlabelString, textdata->onGreeting     ); i++;
1337            }
1338            else
1339            {
1340              sprintf(buf, textdata->offGreetingFormat,
1341                      textdata->offGreetingUname);
1342              string = XmStringCreate(buf, XmFONTLIST_DEFAULT_TAG);
1343              XtSetArg(argt[i], XmNlabelString, string    ); i++;
1344              free(textdata->offGreetingUname);
1345            }
1346            XtSetValues(greeting, argt, i);
1347            /* set the dt_label with the session that is enabled */
1348            SetDtLabelAndIcon();
1349
1350         }
1351
1352         XtSetSensitive(ok_button, True);
1353         XtSetSensitive(clear_button, True);
1354         XtSetSensitive(options_button, True);
1355         XtSetSensitive(help_button, True);
1356
1357         XUngrabKeyboard(dpyinfo.dpy,CurrentTime);
1358       }
1359       break;
1360 #ifdef SIA
1361     case REQUEST_OP_FORM:
1362       {
1363       RequestForm *r = (RequestForm *)buf;
1364       int i;
1365       char *prompt_ptr;
1366
1367 #ifdef VG_TRACE
1368       vg_TRACE_EXECUTION("main:  got REQUEST_OP_FORM ...");
1369 #endif /* VG_TRACE */
1370       siaFormInfo.num_prompts = r->num_prompts;
1371       siaFormInfo.rendition = r->rendition;
1372       siaFormInfo.title = XtMalloc(strlen(buf + r->offTitle));
1373       strcpy(siaFormInfo.title, buf + r->offTitle);
1374
1375       prompt_ptr = buf + r->offPrompts;
1376
1377       for (i=0; i < siaFormInfo.num_prompts; i++)
1378           {
1379           siaFormInfo.visible[i] = r->visible[i];
1380           siaFormInfo.prompts[i] = XtMalloc(strlen(prompt_ptr));
1381           siaFormInfo.answers[i] = NULL;
1382           strcpy(siaFormInfo.prompts[i], prompt_ptr);
1383           prompt_ptr += strlen(prompt_ptr) + 1;
1384           }
1385
1386       /*
1387        * Create Widgets:
1388        *  Form
1389        *   Title
1390        *   prompt labels and answer text fields for each prompt
1391        *   OK button
1392        * Add callbacks as needed.  If not visible don't echo.
1393        * On OK callback, collect info and send it.  Destroy widgets.
1394        */
1395        SiaForm(&siaFormInfo);
1396
1397       }
1398       break;
1399 #endif /* SIA */
1400   }
1401
1402
1403 #if 0
1404   {
1405    /*
1406     * Send immediate response to debug.
1407     */
1408     char outbuf[512];
1409     char *p;
1410     ResponseDebug *rdebug = (ResponseDebug *)outbuf;
1411
1412     rdebug->hdr.opcode = REQUEST_OP_DEBUG;
1413     rdebug->hdr.reserved = 0;
1414     rdebug->offString = sizeof(*rdebug);
1415     p = ((char *)(rdebug)) + rdebug->offString;
1416     strcpy(p, "This is my debug string");
1417     rdebug->hdr.length = sizeof(*rdebug) + strlen(p) + 1;
1418     
1419     TellRequester(outbuf, (size_t) rdebug->hdr.length);
1420   } 
1421 #endif
1422 }
1423
1424 /***************************************************************************
1425  *
1426  *  RespondExitCB
1427  *
1428  *  Respond to an exit request from client
1429  ***************************************************************************/
1430
1431 void 
1432 RespondExitCB(
1433         Widget w,
1434         XtPointer client,
1435         XtPointer call)
1436 {
1437   char buf[REQUEST_LIM_MAXLEN];
1438   ResponseExit *r = (ResponseExit *)buf;
1439
1440 #ifdef VG_TRACE
1441   vg_TRACE_EXECUTION("main:  entered RespondExitCB ...");
1442 #endif /* VG_TRACE */
1443
1444   r->hdr.opcode = REQUEST_OP_EXIT;
1445   r->hdr.reserved = 0;
1446   r->hdr.length = sizeof(*r);
1447
1448   TellRequester(buf, (size_t) r->hdr.length);
1449
1450   CleanupAndExit(NULL, NOTIFY_OK);
1451 }
1452 /***************************************************************************
1453  *
1454  *  RespondLangCB
1455  *
1456  *  Respond to a lang item selection from user
1457  ***************************************************************************/
1458 int amChooser = 0;
1459 int orig_argc;
1460 char **orig_argv;
1461
1462 void
1463 RespondLangCB( Widget w, XtPointer client, XtPointer call)
1464 {
1465   XtSetArg(argt[0], XmNset, True);
1466   XtSetValues(w, argt, 1);
1467
1468 #ifdef VG_TRACE
1469   vg_TRACE_EXECUTION("main:  entered RespondLangCB ...");
1470 #endif /* VG_TRACE */
1471
1472   if (amChooser) {
1473         /** this is probably not the ideal way to do this **/
1474         /** but it does work ok.                          **/
1475         /** notice the related code in chooser.c at the   **/
1476         /** beginning of main.                            **/
1477         char buff[128];
1478         if (XmToggleButtonGadgetGetState(w)) {
1479             strcpy(buff, "LANG="); 
1480             strcat(buff, client);
1481             putenv(buff);
1482             execv(orig_argv[0], orig_argv);
1483         }
1484   } else {
1485     char buf[REQUEST_LIM_MAXLEN];
1486     ResponseLang *r = (ResponseLang *)buf;
1487     char *p;
1488   
1489     r->hdr.opcode = REQUEST_OP_LANG;
1490     r->hdr.reserved = 0;
1491     r->offLang = sizeof(*r);
1492     p = ((char *)(r)) + r->offLang;
1493     strcpy(p, XmToggleButtonGadgetGetState(w) ? client : "default");
1494     r->hdr.length = sizeof(*r) + strlen(p) + 1;
1495
1496     TellRequester(buf, (size_t) r->hdr.length);
1497  
1498     CleanupAndExit(NULL, NOTIFY_LANG_CHANGE);
1499   }
1500 }
1501
1502 /***************************************************************************
1503  *
1504  *  RespondChallengeCB
1505  *
1506  *  Respond to a challenge request from client
1507  ***************************************************************************/
1508
1509 void 
1510 RespondChallengeCB(
1511         Widget w,
1512         XtPointer client,
1513         XtPointer call)
1514 {
1515   char buf[REQUEST_LIM_MAXLEN];
1516   ResponseChallenge *r = (ResponseChallenge *)buf;
1517   char *value;
1518   char *p;
1519   LoginTextPtr textdata;
1520
1521 #ifdef VG_TRACE
1522   vg_TRACE_EXECUTION("main:  entered RespondChallengeCB ...");
1523 #endif /* VG_TRACE */
1524
1525   XtSetSensitive(ok_button, False);
1526   XtSetSensitive(clear_button, False);
1527   XtSetSensitive(options_button, False);
1528   XtSetSensitive(help_button, False);
1529
1530   textdata = GetLoginTextPtr(login_text);
1531
1532  /*
1533   * Get username and password. Username is obtained from widget
1534   * while password is stored in global buffer.
1535   */
1536   if (textdata->bEcho)
1537   {
1538     value = XmTextFieldGetString(login_text);
1539     textdata->offGreetingUname = strdup(value);
1540     userName = strdup(value);
1541     if (strlen(textdata->offGreetingUname) > (size_t) 16)
1542     {
1543       textdata->offGreetingUname[16] = '\0';
1544       userName[16] = '\0';
1545     }
1546   }
1547   else
1548   {
1549     value = textdata->noechobuf;
1550   }
1551
1552   r->hdr.opcode = REQUEST_OP_CHALLENGE;
1553   r->hdr.reserved = 0;
1554   r->offResponse = sizeof(*r);
1555   p = buf + r->offResponse;
1556   strcpy(p, value);
1557   r->hdr.length = r->offResponse + strlen(p) + 1; 
1558
1559   if (textdata->bEcho)
1560   {
1561     XtFree(value);
1562     XmTextFieldSetString(login_text, "");
1563   }
1564   else
1565   {
1566    /*
1567     * Clean password memory to foil snoopers.
1568     */
1569     bzero(textdata->noechobuf, strlen(textdata->noechobuf));
1570   }
1571
1572   TellRequester(buf, (size_t) r->hdr.length);
1573 }
1574
1575 /***************************************************************************
1576  *
1577  *  RespondDialogCB
1578  *
1579  *  Respond to a request that displayed a dialog
1580  ***************************************************************************/
1581
1582 void 
1583 RespondDialogCB(
1584         Widget w,
1585         XtPointer client,
1586         XtPointer call_data)
1587 {
1588   char buf[REQUEST_LIM_MAXLEN];
1589   XmAnyCallbackStruct *reason = (XmAnyCallbackStruct *)call_data;
1590
1591 #ifdef VG_TRACE
1592   vg_TRACE_EXECUTION("main:  entered RespondDialogCB ...");
1593 #endif /* VG_TRACE */
1594
1595   if (w == error_message)
1596   {
1597   ResponseMessage *r= (ResponseMessage *)buf;
1598
1599   r->hdr.opcode = REQUEST_OP_MESSAGE;
1600   r->hdr.reserved = 0;
1601   r->hdr.length = sizeof(*r);
1602
1603   TellRequester(buf, (size_t) r->hdr.length);
1604   } 
1605   else if (w == passwd_message)
1606   {
1607     if (reason->reason == XmCR_OK)
1608     {
1609       CleanupAndExit(w, NOTIFY_PASSWD_EXPIRED);
1610     } 
1611     else
1612     {
1613   ResponseExpassword *r= (ResponseExpassword *)buf;
1614
1615   r->hdr.opcode = REQUEST_OP_EXPASSWORD;
1616   r->hdr.reserved = 0;
1617   r->hdr.length = sizeof(*r);
1618
1619   TellRequester(buf, (size_t) r->hdr.length);
1620     }
1621   }
1622   else if (w == hostname_message)
1623   {
1624     if (reason->reason == XmCR_OK)
1625     {
1626       CleanupAndExit(w, NOTIFY_OK);
1627     } 
1628     else
1629     {
1630       CleanupAndExit(w, NOTIFY_NO_WINDOWS);
1631     }
1632   }
1633 }
1634
1635 /***************************************************************************
1636  *
1637  *  SetDefaultDt
1638  *
1639  *  save the default dt widget.
1640  **************************************************************************/
1641 void
1642 SetDefaultDt(Widget w)
1643 {
1644     default_dt = w;
1645 }
1646
1647 /***************************************************************************
1648  *
1649  *  SetDtLabelAndIcon
1650  *
1651  *  label to display in the dt_label widget and 
1652  *  the logo to display in logo_pixmap 
1653  **************************************************************************/
1654 void
1655 SetDtLabelAndIcon()
1656 {
1657   static XmString       blanks = NULL;
1658   int                   i;
1659   char                  *logoFile;
1660   char                  *logoName;
1661   char                  *temp_p;
1662    
1663 #ifdef VG_TRACE
1664   vg_TRACE_EXECUTION("main:  entered SetDtLabelAndIcon ...");
1665 #endif /* VG_TRACE */
1666
1667   if (NULL == blanks)
1668     blanks = XmStringCreateLocalized("       ");
1669
1670   /*
1671    *  if user is logging in, set dt_label desired. No more than
1672    *  one desktop  can be selected at a time ...
1673    */
1674   i = 0;
1675   XtSetArg(argt[0], XmNset, FALSE); i++;
1676  
1677   XtSetValues(options_failsafe, argt, i);
1678   XtSetValues(options_dtlite, argt, i);
1679   XtSetValues(options_dt, argt, i);
1680   if (options_last_dt != NULL)
1681     XtSetValues(options_last_dt, argt, i);
1682  
1683   for(i = 0; i<appInfo.altDts ; ++i)
1684     if(alt_dts[i] != NULL)
1685       XtSetValues(alt_dts[i], argt, i);
1686
1687   if (NULL != default_dt) {
1688       i = 0;
1689       XtSetArg(argt[i], XmNset, True); i++;
1690       XtSetValues(default_dt, argt, i);
1691
1692       if(default_dt == options_last_dt)
1693         xmstr = blanks;
1694       else
1695       {
1696          i = 0;
1697          XtSetArg(argt[i], XmNlabelString, &xmstr); i++;
1698          XtGetValues(default_dt, argt, i);  
1699       }
1700       
1701       i = 0;
1702       XtSetArg(argt[i], XmNuserData, &logoFile); i++;
1703       XtGetValues(default_dt, argt, i);
1704   }
1705   else {
1706       xmstr = blanks;
1707       logoFile = logoInfo.bitmapFile;
1708   }
1709
1710 #ifdef FIX_FOR_DEFECT_CDExc19307
1711   /*
1712    *  This code causes the Session toggle buttons to be reset
1713    *  to the default setting when the user commits a typing error.
1714    *  NOT very user friendly.
1715    *
1716    *  As for setting the defaults after the user is done entering
1717    *  the we could do the same thing by passing in an argument.  For
1718    *  now, I'm not convinced that it is required.
1719    */
1720
1721   /*
1722    * to set the defaults  after the user is done                         
1723    * entering the login .. 
1724    */
1725    if (strcmp(userName,"\0") != 0)
1726      strcpy(userName,"\0");  
1727 #endif
1728
1729   i = 0;
1730   XtSetArg(argt[i], XmNlabelString, xmstr); i++;
1731   XtSetValues(dt_label, argt, i); 
1732
1733   /* 
1734    * remove trailing spaces 
1735    */
1736   if(strchr(logoFile,' '))
1737      temp_p = strtok(logoFile," ");
1738   else
1739      temp_p = logoFile;
1740  
1741   logoName = _DtGetIconFileName(
1742                         DefaultScreenOfDisplay(dpyinfo.dpy),
1743                         temp_p, NULL, NULL, 0);
1744  
1745   if (logoName == NULL) {
1746         LogError(
1747         ReadCatalog(MC_LOG_SET,MC_LOG_NO_LOGOBIT,MC_DEF_LOG_NO_LOGOBIT),
1748                              logoFile);
1749         logoFile = NULL;
1750   }
1751
1752   i = 0;
1753   XtSetArg(argt[i], XmNimageName, logoName); i++;
1754   XtSetValues(logo_pixmap, argt, i);
1755 }
1756
1757 /***************************************************************************
1758  *
1759  *  _DtShowDialog
1760  *
1761  *  display a dialog message box
1762  ***************************************************************************/
1763
1764 static void 
1765 _DtShowDialog( DialogType dtype, XmString msg)
1766 {
1767     Widget *w;
1768     
1769 #ifdef VG_TRACE
1770     vg_TRACE_EXECUTION("main:  entered _DtShowDialog ...");
1771 #endif /* VG_TRACE */
1772
1773     switch (dtype) {
1774       case copyright:  w = &copyright_msg; break;
1775       case error:      w = &error_message; break;
1776       case expassword: w = &passwd_message; break;
1777       case help:       w = &help_message; break;
1778       case hostname:   w = &hostname_message; break;
1779       case help_chooser: w = &help_message; break;
1780     }
1781
1782     if (*w == NULL)
1783     {
1784       MakeDialog(dtype);
1785     }
1786     
1787     if ( msg != NULL ) {
1788         XtSetArg(argt[0], XmNmessageString, msg );
1789         XtSetValues(*w, argt, 1);
1790     }
1791
1792     XtManageChild(*w);
1793
1794     XSetInputFocus(XtDisplay(*w), XtWindow(*w), 
1795                    RevertToPointerRoot, CurrentTime);
1796 }    
1797
1798
1799
1800
1801 /***************************************************************************
1802  *
1803  *  ShowDialogCB
1804  *
1805  *  callback to display a dialog message box
1806  ***************************************************************************/
1807
1808 void 
1809 ShowDialogCB( Widget w, XtPointer dialog, XtPointer call_data )
1810 {
1811
1812     _DtShowDialog( (DialogType) dialog, NULL);
1813 }
1814
1815
1816
1817
1818 /***************************************************************************
1819  *
1820  *  TextFocusCB
1821  *
1822  *  set focusWidget global variable when focus changes
1823  ***************************************************************************/
1824
1825
1826 void 
1827 TextFocusCB( Widget w, XtPointer client_data, XtPointer call_data )
1828 {
1829     if ( w == login_text )
1830         focusWidget = w;
1831 }
1832
1833 /***************************************************************************
1834  *
1835  *  GetLoginTextPtr
1836  *
1837  *  Return login text widget instance data
1838  ***************************************************************************/
1839
1840 LoginTextPtr
1841 GetLoginTextPtr( Widget w )
1842 {
1843   LoginTextPtr textdata;
1844   int i;
1845
1846   i = 0;
1847   XtSetArg(argt[i], XmNuserData,     &textdata              ); i++;
1848   XtGetValues(w, argt, i);
1849
1850   return(textdata);
1851 }
1852
1853
1854 #ifdef BLS
1855 /***************************************************************************
1856  *
1857  *  PromptSensitivityLevel
1858  *
1859  *  Prompt for B1 Sensitivity Level. The password widget set is reused for
1860  *  this purpose rather than creating another complete widget set. It already
1861  *  has most of the proper size and alignment specifications needed. Using
1862  *  the password set also allows the B1 code changes to be more localized.
1863  *
1864  ***************************************************************************/
1865
1866 static void 
1867 PromptSensitivityLevel( void)
1868 {
1869
1870     Dimension   width;
1871     int         i, width1, width2;
1872
1873     /*
1874      *  Use the password widget set to prompt for the B1 Sensitivity Level.
1875      *  Remember to put it back to normal if the user presses [Clear].
1876      */
1877      
1878     normalPasswordWidget = False;
1879     
1880     XtRemoveAllCallbacks(_text, XmNmodifyVerifyCallback);
1881     XmTextFieldSetString(_text,"");
1882
1883
1884     /*
1885      *  Change the label and resize the password form...
1886      */
1887      
1888     i = 0;
1889     XtSetArg(argt[i], XmNresizable,             True                    ); i++;
1890     XtSetArg(argt[i], XmNresizePolicy,          XmRESIZE_ANY            ); i++;
1891     XtSetValues(_form, argt, i);
1892
1893     i = 0;
1894     xmstr = ReadCatalogXms(MC_LABEL_SET, -1, "Sensitivity Level:");
1895     XtSetArg(argt[i], XmNrecomputeSize,         True                    ); i++;
1896     XtSetArg(argt[i], XmNlabelString,           xmstr                   ); i++;
1897     XtSetValues(_label, argt, i);
1898
1899     XmStringFree(xmstr);
1900     
1901     /*
1902      *  Center the form horizontally in the login_matte...
1903      *
1904      */
1905
1906     CenterForm(matte1, _form);
1907     
1908     ProcessTraversal(_text, XmTRAVERSE_CURRENT);
1909
1910 }
1911
1912 #endif /* BLS */
1913
1914
1915 static void
1916 TellRequester(char * buf, size_t nbytes)
1917 {
1918 #ifdef VG_TRACE
1919   vg_TRACE_EXECUTION("main:  entered TellRequester ...");
1920 #endif /* VG_TRACE */
1921   write(1, buf, nbytes);
1922 }