http://ftp.aanet.ru/pub/Linux/X11/apps/xscreensaver-2.31.tar.gz
[xscreensaver] / driver / test-passwd.c
1 /* xscreensaver, Copyright (c) 1998 Jamie Zawinski <jwz@jwz.org>
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or 
9  * implied warranty.
10  */
11
12 /* This is a kludgy test harness for debugging the password dialog box.
13    It's somewhat easier to debug it here than in the xscreensaver executable
14    itself.
15  */
16
17 #ifdef HAVE_CONFIG_H
18 # include "config.h"
19 #endif
20
21 #include <stdio.h>
22 #include <ctype.h>
23 #include <X11/Xlib.h>
24 #include <X11/Xatom.h>
25 #include <X11/Intrinsic.h>
26 #include <X11/StringDefs.h>
27 #include <X11/Shell.h>
28
29 #include "xscreensaver.h"
30 #include "resources.h"
31 #include "version.h"
32
33 char *progname = 0;
34 char *progclass = 0;
35 XrmDatabase db = 0;
36 saver_info *global_si_kludge;
37
38 FILE *real_stderr, *real_stdout;
39
40 void reset_stderr(saver_screen_info *ssi) {}
41 void clear_stderr(saver_screen_info *ssi) {}
42 void reset_watchdog_timer(saver_info *si, Bool on_p) {}
43 void monitor_power_on (saver_info *si) {}
44 void ungrab_keyboard_and_mouse (saver_info *si) {}
45 Bool select_visual (saver_screen_info *ssi, const char *v) { return False; }
46 void raise_window (saver_info *si, Bool i, Bool b, Bool d) {}
47 void restore_real_vroot (saver_info *si) {}
48 void saver_exit (saver_info *si, int status, const char *core) { exit(status);}
49 const char * signal_name(int signal) { return "???"; }
50 Bool monitor_powered_on_p (saver_info *si) { return True; }
51 void start_notice_events_timer (saver_info *si, Window w) {}
52 void initialize_screensaver_window (saver_info *si) {}
53 void blank_screen (saver_info *si) {}
54 void unblank_screen (saver_info *si) {}
55 Bool handle_clientmessage (saver_info *si, XEvent *e, Bool u) { return False; }
56 int BadWindow_ehandler (Display *dpy, XErrorEvent *error) { exit(1); }
57
58 const char *blurb(void) { return progname; }
59
60 void
61 idle_timer (XtPointer closure, XtIntervalId *id)
62 {
63   saver_info *si = (saver_info *) closure;
64   XEvent fake_event;
65   fake_event.type = 0;  /* XAnyEvent type, ignored. */
66   fake_event.xany.display = si->dpy;
67   fake_event.xany.window  = 0;
68   XPutBackEvent (si->dpy, &fake_event);
69 }
70
71
72 static char *
73 reformat_hack(const char *hack)
74 {
75   int i;
76   const char *in = hack;
77   int indent = 13;
78   char *h2 = (char *) malloc(strlen(in) + indent + 2);
79   char *out = h2;
80
81   while (isspace(*in)) in++;            /* skip whitespace */
82   while (*in && !isspace(*in) && *in != ':')
83     *out++ = *in++;                     /* snarf first token */
84   while (isspace(*in)) in++;            /* skip whitespace */
85
86   if (*in == ':')
87     *out++ = *in++;                     /* copy colon */
88   else
89     {
90       in = hack;
91       out = h2;                         /* reset to beginning */
92     }
93
94   *out = 0;
95
96   while (isspace(*in)) in++;            /* skip whitespace */
97   for (i = strlen(h2); i < indent; i++) /* indent */
98     *out++ = ' ';
99
100   while (*in) *out++ = *in++;           /* copy rest of line */
101   *out = 0;
102
103   return h2;
104 }
105
106
107 static void
108 get_screenhacks (saver_info *si)
109 {
110   saver_preferences *p = &si->prefs;
111   int i = 0;
112   int hacks_size = 60;
113   int size;
114   char *d;
115
116   d = get_string_resource ("monoPrograms", "MonoPrograms");
117   if (d && !*d) { free(d); d = 0; }
118   if (!d)
119     d = get_string_resource ("colorPrograms", "ColorPrograms");
120   if (d && !*d) { free(d); d = 0; }
121
122   if (d)
123     {
124       fprintf (stderr,
125        "%s: the `monoPrograms' and `colorPrograms' resources are obsolete;\n\
126         see the manual for details.\n", blurb());
127       free(d);
128     }
129
130   d = get_string_resource ("programs", "Programs");
131
132   size = d ? strlen (d) : 0;
133   p->screenhacks = (char **) malloc (sizeof (char *) * hacks_size);
134   p->screenhacks_count = 0;
135
136   while (i < size)
137     {
138       int end, start = i;
139       if (d[i] == ' ' || d[i] == '\t' || d[i] == '\n' || d[i] == 0)
140         {
141           i++;
142           continue;
143         }
144       if (hacks_size <= p->screenhacks_count)
145         p->screenhacks = (char **) realloc (p->screenhacks,
146                                             (hacks_size = hacks_size * 2) *
147                                             sizeof (char *));
148       p->screenhacks [p->screenhacks_count++] = d + i;
149       while (d[i] != 0 && d[i] != '\n')
150         i++;
151       end = i;
152       while (i > start && (d[i-1] == ' ' || d[i-1] == '\t'))
153         i--;
154       d[i] = 0;
155       i = end + 1;
156     }
157
158   /* shrink all whitespace to one space, for the benefit of the "demo"
159      mode display.  We only do this when we can easily tell that the
160      whitespace is not significant (no shell metachars).
161    */
162   for (i = 0; i < p->screenhacks_count; i++)
163     {
164       char *s = p->screenhacks [i];
165       char *s2;
166       int L = strlen (s);
167       int j, k;
168       for (j = 0; j < L; j++)
169         {
170           switch (s[j])
171             {
172             case '\'': case '"': case '`': case '\\':
173               goto DONE;
174             case '\t':
175               s[j] = ' ';
176             case ' ':
177               k = 0;
178               for (s2 = s+j+1; *s2 == ' ' || *s2 == '\t'; s2++)
179                 k++;
180               if (k > 0)
181                 {
182                   for (s2 = s+j+1; s2[k]; s2++)
183                     *s2 = s2[k];
184                   *s2 = 0;
185                 }
186               break;
187             }
188         }
189     DONE:
190       p->screenhacks[i] = reformat_hack(s);  /* mallocs */
191     }
192
193   if (p->screenhacks_count)
194     {
195       /* Shrink down the screenhacks array to be only as big as it needs to.
196          This doesn't really matter at all. */
197       p->screenhacks = (char **)
198         realloc (p->screenhacks, ((p->screenhacks_count + 1) *
199                                   sizeof(char *)));
200       p->screenhacks [p->screenhacks_count] = 0;
201     }
202   else
203     {
204       free (p->screenhacks);
205       p->screenhacks = 0;
206     }
207 }
208
209
210 int
211 main (int argc, char **argv)
212 {
213   Widget toplevel_shell;
214   saver_screen_info ssip;
215   saver_info sip;
216   saver_info *si = &sip;
217   saver_preferences *p = &si->prefs;
218
219   memset(&sip, 0, sizeof(sip));
220   memset(&ssip, 0, sizeof(ssip));
221
222   si->nscreens = 1;
223   si->screens = si->default_screen = &ssip;
224   ssip.global = si;
225
226   global_si_kludge = si;
227   real_stderr = stderr;
228   real_stdout = stdout;
229
230   si->version = (char *) malloc (5);
231   memcpy (si->version, screensaver_id + 17, 4);
232   progname = argv[0];
233
234 # ifdef SCO
235   set_auth_parameters(argc, argv);
236 # endif /* SCO */
237
238   if (! lock_init (argc, argv)) /* before hack_uid() for proper permissions */
239     {
240       si->locking_disabled_p = True;
241       si->nolock_reason = "error getting password";
242     }
243
244   hack_uid (si);
245
246   progclass = "XScreenSaver";
247
248   toplevel_shell = XtAppInitialize (&si->app, progclass, 0, 0,
249                                     &argc, argv, 0, 0, 0);
250
251   si->dpy = XtDisplay (toplevel_shell);
252   si->db = XtDatabase (si->dpy);
253   si->default_screen->toplevel_shell = toplevel_shell;
254   si->default_screen->screen = XtScreen(toplevel_shell);
255   si->default_screen->default_visual =
256     si->default_screen->current_visual =
257       DefaultVisualOfScreen(si->default_screen->screen);
258   si->default_screen->screensaver_window =
259     RootWindowOfScreen(si->default_screen->screen);
260
261   db = si->db;
262   XtGetApplicationNameAndClass (si->dpy, &progname, &progclass);
263
264   p->debug_p = True;
265   p->verbose_p = True;
266   p->lock_p = True;
267   p->passwd_timeout = 1000 * get_seconds_resource ("passwdTimeout", "Time");
268
269   get_screenhacks(si);
270
271   hack_uid_warn (si);
272
273   while (1)
274     {
275 #if 0
276       if (unlock_p (si))
277         fprintf (stderr, "%s: password correct\n", progname);
278       else
279         fprintf (stderr, "%s: password INCORRECT!\n", progname);
280
281       XSync(si->dpy, False);
282       sleep (3);
283 #else
284       si->demo_mode_p = True;
285       make_screenhack_dialog (si);
286       XtAppMainLoop(si->app);
287 #endif
288     }
289 }