+static Bool
+mac1 (Display *dpy, Window window, int delay)
+{
+ XGCValues gcv;
+ XWindowAttributes xgwa;
+ GC gc;
+ Pixmap pixmap = 0;
+ int pix_w = macbomb_width;
+ int pix_h = macbomb_height;
+
+ if (!get_boolean_resource("doMac1", "DoMac1"))
+ return False;
+
+ XGetWindowAttributes (dpy, window, &xgwa);
+
+ gcv.foreground = get_pixel_resource("mac1.foreground", "Mac.Foreground",
+ dpy, xgwa.colormap);
+ gcv.background = get_pixel_resource("mac1.background", "Mac.Background",
+ dpy, xgwa.colormap);
+ XSetWindowBackground(dpy, window, gcv.background);
+ XClearWindow(dpy, window);
+
+ gc = XCreateGC(dpy, window, GCForeground|GCBackground, &gcv);
+
+ pixmap = XCreatePixmapFromBitmapData(dpy, window, (char *) macbomb_bits,
+ macbomb_width, macbomb_height,
+ gcv.foreground,
+ gcv.background,
+ xgwa.depth);
+
+ {
+ int x = (xgwa.width - pix_w) / 2;
+ int y = (xgwa.height - pix_h) / 2;
+ if (y < 0) y = 0;
+ XFillRectangle (dpy, window, gc, 0, 0, xgwa.width, xgwa.height);
+ XSync(dpy, False);
+ if (bsod_sleep(dpy, 1))
+ goto DONE;
+ XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
+ }
+
+ DONE:
+ XFreeGC(dpy, gc);
+ XFreePixmap(dpy, pixmap);
+ XSync(dpy, False);
+ bsod_sleep(dpy, delay);
+ XClearWindow(dpy, window);
+ return True;
+}
+
+
+static Bool
+macx (Display *dpy, Window window, int delay)
+{
+ XGCValues gcv;
+ XWindowAttributes xgwa;
+ char *fontname = 0;
+ const char *def_font = "fixed";
+ XFontStruct *font;
+ GC gc;
+
+ const char *macx_panic =
+ ("panic(cpu 0): Unable to find driver for this platform: "
+ "\"PowerMac 3,5\".\n"
+ "\n"
+ "backtrace: 0x0008c2f4 0x0002a7a0 0x001f0204 0x001d4e4c 0x001d4c5c "
+ "0x001a56cc 0x01d5dbc 0x001c621c 0x00037430 0x00037364\n"
+ "\n"
+ "\n"
+ "\n"
+ "No debugger configured - dumping debug information\n"
+ "\n"
+ "version string : Darwin Kernel Version 1.3:\n"
+ "Thu Mar 1 06:56:40 PST 2001; root:xnu/xnu-123.5.obj~1/RELEASE_PPC\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n"
+ "DBAT0: 00000000 00000000\n"
+ "DBAT1: 00000000 00000000\n"
+ "DBAT2: 80001FFE 8000003A\n"
+ "DBAT3: 90001FFE 9000003A\n"
+ "MSR=00001030\n"
+ "backtrace: 0x0008c2f4 0x0002a7a0 0x001f0204 0x001d4e4c 0x001d4c5c "
+ "0x001a56cc 0x01d5dbc 0x001c621c 0x00037430 0x00037364\n"
+ "\n"
+ "panic: We are hanging here...\n");
+
+ if (!get_boolean_resource("doMacX", "DoMacX"))
+ return False;
+
+ XGetWindowAttributes (dpy, window, &xgwa);
+
+ gcv.background = get_pixel_resource("macX.background",
+ "MacX.Background",
+ dpy, xgwa.colormap);
+ XSetWindowBackground(dpy, window, gcv.background);
+ XClearWindow(dpy, window);
+
+ fontname = get_string_resource ((xgwa.height > 900
+ ? "macX.font2"
+ : "macX.font"),
+ "MacX.Font");
+ if (!fontname || !*fontname) fontname = (char *)def_font;
+ font = XLoadQueryFont (dpy, fontname);
+ if (!font) font = XLoadQueryFont (dpy, def_font);
+ if (!font) exit(-1);
+ if (fontname && fontname != def_font)
+ free (fontname);
+
+ gcv.font = font->fid;
+ gcv.foreground = get_pixel_resource("macsbug.foreground",
+ "MacsBug.Foreground",
+ dpy, xgwa.colormap);
+ gcv.background = get_pixel_resource("macsbug.background",
+ "MacsBug.Background",
+ dpy, xgwa.colormap);
+
+
+ gcv.foreground = get_pixel_resource("macX.textForeground",
+ "MacX.TextForeground",
+ dpy, xgwa.colormap);
+ gcv.background = get_pixel_resource("macX.textBackground",
+ "MacX.TextBackground",
+ dpy, xgwa.colormap);
+ gc = XCreateGC(dpy, window, GCForeground|GCBackground|GCFont, &gcv);
+
+#if defined(HAVE_GDK_PIXBUF) || defined (HAVE_XPM)
+ {
+ Pixmap pixmap = 0;
+ Pixmap mask = 0;
+ int x, y, pix_w, pix_h;
+ pixmap = xpm_data_to_pixmap (dpy, window, (char **) happy_mac,
+ &pix_w, &pix_h, &mask);
+
+ x = (xgwa.width - pix_w) / 2;
+ y = (xgwa.height - pix_h) / 2;
+ if (y < 0) y = 0;
+ XSync(dpy, False);
+ bsod_sleep(dpy, 2);
+ XSetClipMask (dpy, gc, mask);
+ XSetClipOrigin (dpy, gc, x, y);
+ XCopyArea (dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
+ XSetClipMask (dpy, gc, None);
+ XFreePixmap (dpy, pixmap);
+ }
+#endif /* HAVE_GDK_PIXBUF || HAVE_XPM */
+
+ bsod_sleep(dpy, 3);
+
+ {
+ const char *s;
+ int x = 0, y = 0;
+ int char_width, line_height;
+ char_width = (font->per_char
+ ? font->per_char['n'-font->min_char_or_byte2].width
+ : font->min_bounds.width);
+ line_height = font->ascent + font->descent;
+
+ s = macx_panic;
+ y = font->ascent;
+ while (*s)
+ {
+ int ox = x;
+ int oy = y;
+ if (*s == '\n' || x + char_width >= xgwa.width)
+ {
+ x = 0;
+ y += line_height;
+ }
+
+ if (*s == '\n')
+ {
+ /* Note that to get this goofy effect, they must be actually
+ emitting LF CR at the end of each line instead of CR LF!
+ */
+ XDrawImageString (dpy, window, gc, ox, oy, " ", 1);
+ XDrawImageString (dpy, window, gc, ox, y, " ", 1);
+ }
+ else
+ {
+ XDrawImageString (dpy, window, gc, x, y, s, 1);
+ x += char_width;
+ }
+ s++;
+ }
+ }
+
+ XFreeGC(dpy, gc);
+ XSync(dpy, False);
+ bsod_sleep(dpy, delay);
+ XClearWindow(dpy, window);
+ return True;
+}
+
+
+
+
+\f
+/* blit damage
+ *
+ * by Martin Pool <mbp@samba.org>, Feb 2000.
+ *
+ * This is meant to look like the preferred failure mode of NCD
+ * Xterms. The parameters for choosing what to copy where might not
+ * be quite right, but it looks about ugly enough.
+ */
+static Bool
+blitdamage (Display *dpy, Window window, int delay)
+{
+ XGCValues gcv;
+ XWindowAttributes xwa;
+ GC gc0;
+ int i;
+ int delta_x = 0, delta_y = 0;
+ int w, h;
+ int chunk_h, chunk_w;
+ int steps;
+ long gc_mask = 0;
+ int src_x, src_y;
+ int x, y;
+
+ if (!get_boolean_resource("doBlitDamage", "DoBlitDamage"))
+ return False;
+
+ XGetWindowAttributes(dpy, window, &xwa);
+
+ grab_screen_image(xwa.screen, window);
+
+ w = xwa.width;
+ h = xwa.height;
+
+ gc_mask = GCForeground;
+
+ gcv.plane_mask = random();
+ gc_mask |= GCPlaneMask;
+
+ gc0 = XCreateGC(dpy, window, gc_mask, &gcv);
+
+ steps = 50;
+ chunk_w = w / (random() % 1 + 1);
+ chunk_h = h / (random() % 1 + 1);
+ if (random() & 0x1000)
+ delta_y = random() % 600;
+ if (!delta_y || (random() & 0x2000))
+ delta_x = random() % 600;
+ src_x = 0;
+ src_y = 0;
+ x = 0;
+ y = 0;
+
+ for (i = 0; i < steps; i++) {
+ if (x + chunk_w > w)
+ x -= w;
+ else
+ x += delta_x;
+
+ if (y + chunk_h > h)
+ y -= h;
+ else
+ y += delta_y;
+
+ XCopyArea(dpy, window, window, gc0,
+ src_x, src_y,
+ chunk_w, chunk_h,
+ x, y);
+
+ if (bsod_sleep(dpy, 0))
+ goto DONE;
+ }
+
+ bsod_sleep(dpy, delay);
+
+ DONE:
+ XFreeGC(dpy, gc0);
+
+ return True;
+}
+
+\f
+/*
+ * SPARC Solaris panic. Should look pretty authentic on Solaris boxes.
+ * Anton Solovyev <solovam@earthlink.net>
+ */
+
+typedef struct
+{
+ Display *dpy;
+ Window window;
+ GC gc, erase_gc;
+ XFontStruct *xfs;
+ int sub_width; /* Text subwindow width in pixels */
+ int sub_height; /* Text subwindow height in pixels */
+ int sub_x; /* upper left corner of the text subwindow */
+ int sub_y; /* upper left corner of the text subwindow */
+ int char_width; /* Char width in pixels */
+ int line_height; /* Line height in pixels */
+ int columns; /* Number of columns in the text screen */
+ int x; /* horizontal position of the cursor */
+} scrolling_window;
+
+
+static scrolling_window *
+make_scrolling_window (Display *dpy, Window window,
+ const char *name,
+ Bool grab_screen_p)
+{
+ const char *def_font = "fixed";
+ scrolling_window* ts;
+ XWindowAttributes xgwa;
+ XGCValues gcv;
+ char* fn;
+ char buf1[100], buf2[100];
+
+ ts = malloc (sizeof (*ts));
+ ts->window = window;
+ ts->dpy = dpy;
+
+ ts->x = 0;
+
+ XGetWindowAttributes (dpy, window, &xgwa);
+
+ if (grab_screen_p)
+ {
+ ts->sub_width = xgwa.width * 0.8;
+ ts->sub_height = xgwa.height * 0.8;
+ }
+ else
+ {
+ ts->sub_width = xgwa.width - 20;
+ ts->sub_height = xgwa.height - 20;
+ if (ts->sub_width < 20) ts->sub_width = 20;
+ if (ts->sub_height < 20) ts->sub_height = 20;
+ }
+
+ sprintf (buf1, "%.50s.font", name);
+ sprintf (buf2, "%.50s.Font", name);
+ fn = get_string_resource (buf1, buf2);
+ ts->xfs = XLoadQueryFont (dpy, fn);
+ if (!ts->xfs)
+ {
+ sprintf (buf1, "%.50s.font2", name);
+ fn = get_string_resource(buf1, buf2);
+ ts->xfs = XLoadQueryFont(dpy, fn);
+ }
+ if (!ts->xfs)
+ ts->xfs = XLoadQueryFont(dpy, def_font);
+ if (!ts->xfs)
+ exit (1);
+ gcv.font = ts->xfs->fid;
+ ts->char_width = (ts->xfs->per_char
+ ? ts->xfs->per_char['n'-ts->xfs->min_char_or_byte2].width
+ : ts->xfs->min_bounds.width);
+ ts->line_height = ts->xfs->ascent + ts->xfs->descent + 1;
+
+ ts->columns = ts->sub_width / ts->char_width;
+
+ ts->sub_x = (xgwa.width - ts->sub_width) / 2;
+ ts->sub_y = (xgwa.height - ts->sub_height) / 2;
+
+ if (!grab_screen_p) ts->sub_height += ts->sub_y, ts->sub_y = 0;
+
+ if (grab_screen_p)
+ grab_screen_image (xgwa.screen, window);
+
+ sprintf (buf1, "%.50s.background", name);
+ sprintf (buf2, "%.50s.Background", name);
+ gcv.background = get_pixel_resource (buf1, buf2, dpy, xgwa.colormap);
+
+ sprintf (buf1, "%.50s.foreground", name);
+ sprintf (buf2, "%.50s.Foreground", name);
+ gcv.foreground = get_pixel_resource (buf1, buf2, dpy, xgwa.colormap);
+
+ ts->gc = XCreateGC (dpy, window,
+ GCForeground | GCBackground | GCFont,
+ &gcv);
+ gcv.foreground = gcv.background;
+ ts->erase_gc = XCreateGC (dpy, window,
+ GCForeground | GCBackground,
+ &gcv);
+ XSetWindowBackground (dpy, window, gcv.background);
+ return(ts);
+}
+
+static void
+free_scrolling_window (scrolling_window* ts)
+{
+ XFreeGC (ts->dpy, ts->gc);
+ XFreeGC (ts->dpy, ts->erase_gc);
+ XFreeFont (ts->dpy, ts->xfs);
+ free (ts);
+}
+
+static void
+scrolling_putc (scrolling_window* ts, const char aChar)
+{
+ switch (aChar)
+ {
+ case '\n':
+ ts->x = 0;
+ XCopyArea (ts->dpy, ts->window, ts->window, ts->gc,
+ ts->sub_x, ts->sub_y + ts->line_height,
+ ts->sub_width, ts->sub_height,
+ ts->sub_x, ts->sub_y);
+ XFillRectangle (ts->dpy, ts->window, ts->erase_gc,
+ ts->sub_x, ts->sub_y + ts->sub_height - ts->line_height,
+ ts->sub_width, ts->line_height);
+ break;
+ case '\b':
+ if(ts->x > 0)
+ ts->x--;
+ break;
+ default:
+ if (ts->x >= ts->columns)
+ scrolling_putc (ts, '\n');
+ XDrawImageString (ts->dpy, ts->window, ts->gc,
+ (ts->sub_x +
+ (ts->x * ts->char_width)
+ - ts->xfs->min_bounds.lbearing),
+ (ts->sub_y + ts->sub_height - ts->xfs->descent),
+ &aChar, 1);
+ ts->x++;
+ break;
+ }
+}
+
+static Bool
+scrolling_puts (scrolling_window *ts, const char* aString, int delay)
+{
+ const char *c;
+ for (c = aString; *c; ++c)
+ {
+ scrolling_putc (ts, *c);
+ if (delay)
+ {
+ XSync(ts->dpy, 0);
+ usleep(delay);
+ if (bsod_sleep (ts->dpy, 0))
+ return True;
+ }
+ }
+ XSync (ts->dpy, 0);
+ return False;
+}
+
+static Bool
+sparc_solaris (Display* dpy, Window window, int delay)
+{
+ const char *msg1 =
+ "BAD TRAP: cpu=0 type=0x31 rp=0x2a10043b5e0 addr=0xf3880 mmu_fsr=0x0\n"
+ "BAD TRAP occured in module \"unix\" due to an illegal access to a"
+ " user address.\n"
+ "adb: trap type = 0x31\n"
+ "addr=0xf3880\n"
+ "pid=307, pc=0x100306e4, sp=0x2a10043ae81, tstate=0x4480001602,"
+ " context=0x87f\n"
+ "g1-g7: 1045b000, 32f, 10079440, 180, 300000ebde8, 0, 30000953a20\n"
+ "Begin traceback... sp = 2a10043ae81\n"
+ "Called from 100bd060, fp=2a10043af31, args=f3700 300008cc988 f3880 0"
+ " 1 300000ebde0.\n"
+ "Called from 101fe1bc, fp=2a10043b011, args=3000045a240 104465a0"
+ " 300008e47d0 300008e48fa 300008ae350 300008ae410\n"
+ "Called from 1007c520, fp=2a10043b0c1, args=300008e4878 300003596e8 0"
+ " 3000045a320 0 3000045a220\n"
+ "Called from 1007c498, fp=2a10043b171, args=1045a000 300007847f0 20"
+ " 3000045a240 1 0\n"
+ "Called from 1007972c, fp=2a10043b221, args=1 300009517c0 30000951e58 1"
+ " 300007847f0 0\n"
+ "Called from 10031e10, fp=2a10043b2d1, args=3000095b0c8 0 300009396a8"
+ " 30000953a20 0 1\n"
+ "Called from 10000bdd8, fp=ffffffff7ffff1c1, args=0 57 100131480"
+ " 100131480 10012a6e0 0\n"
+ "End traceback...\n"
+ "panic[cpu0]/thread=30000953a20: trap\n"
+ "syncing file systems...";
+ const char *msg2 =
+ " 1 done\n"
+ "dumping to /dev/dsk/c0t0d0s3, offset 26935296\n";
+ const char *msg3 =
+ ": 2803 pages dumped, compression ratio 2.88, dump succeeded\n";
+ const char *msg4 =
+ "rebooting...\n"
+ "Resetting ...";
+
+ scrolling_window *ts;
+ int i;
+ char buf[256];
+
+ if (!get_boolean_resource("doSolaris", "DoSolaris"))
+ return False;
+
+ ts = make_scrolling_window (dpy, window, "Solaris", True);
+
+ scrolling_puts (ts, msg1, 0);
+ if (bsod_sleep (dpy, 3))
+ goto DONE;
+
+ scrolling_puts (ts, msg2, 0);
+ if (bsod_sleep (dpy, 2))
+ goto DONE;
+
+ for (i = 1; i <= 100; ++i)
+ {
+ sprintf(buf, "\b\b\b\b\b\b\b\b\b\b\b%3d%% done", i);
+ scrolling_puts (ts, buf, 0);
+ if (bsod_sleep (dpy, -1))
+ goto DONE;
+ }
+
+ scrolling_puts (ts, msg3, 0);
+ if (bsod_sleep (dpy, 2))
+ goto DONE;
+
+ scrolling_puts (ts, msg4, 0);
+ if (bsod_sleep(dpy, 3))
+ goto DONE;
+
+ bsod_sleep (dpy, 3);
+
+ DONE:
+ free_scrolling_window (ts);
+
+ return True;
+}
+
+/* Linux panic and fsck, by jwz
+ */
+static Bool
+linux_fsck (Display *dpy, Window window, int delay)
+{
+ XWindowAttributes xgwa;
+ scrolling_window *ts;
+ int i;
+ const char *sysname;
+ char buf[1024];
+
+ const char *linux_panic[] = {
+ " kernel: Unable to handle kernel paging request at virtual "
+ "address 0000f0ad\n",
+ " kernel: printing eip:\n",
+ " kernel: c01becd7\n",
+ " kernel: *pde = 00000000\n",
+ " kernel: Oops: 0000\n",
+ " kernel: CPU: 0\n",
+ " kernel: EIP: 0010:[<c01becd7>] Tainted: P \n",
+ " kernel: EFLAGS: 00010286\n",
+ " kernel: eax: 0000ff00 ebx: ca6b7e00 ecx: ce1d7a60 edx: ce1d7a60\n",
+ " kernel: esi: ca6b7ebc edi: 00030000 ebp: d3655ca0 esp: ca6b7e5c\n",
+ " kernel: ds: 0018 es: 0018 ss: 0018\n",
+ " kernel: Process crond (pid: 1189, stackpage=ca6b7000)\n",
+ " kernel: Stack: d3655ca0 ca6b7ebc 00030054 ca6b7e7c c01c1e5b "
+ "00000287 00000020 c01c1fbf \n",
+ "",
+ " kernel: 00005a36 000000dc 000001f4 00000000 00000000 "
+ "ce046d40 00000001 00000000 \n",
+ "", "", "",
+ " kernel: ffffffff d3655ca0 d3655b80 00030054 c01bef93 "
+ "d3655ca0 ca6b7ebc 00030054 \n",
+ "", "", "",
+ " kernel: Call Trace: [<c01c1e5b>] [<c01c1fbf>] [<c01bef93>] "
+ "[<c01bf02b>] [<c0134c4f>]\n",
+ "", "", "",
+ " kernel: [<c0142562>] [<c0114f8c>] [<c0134de3>] [<c010891b>]\n",
+ " kernel: \n",
+ " kernel: Code: 2a 00 75 08 8b 44 24 2c 85 c0 74 0c 8b 44 24 58 83 48 18 "
+ "08 \n",
+ 0
+ };
+
+ if (!get_boolean_resource("doLinux", "DoLinux"))
+ return False;
+
+ XGetWindowAttributes (dpy, window, &xgwa);
+ XSetWindowBackground (dpy, window,
+ get_pixel_resource("Linux.background",
+ "Linux.Background",
+ dpy, xgwa.colormap));
+ XClearWindow(dpy, window);
+
+ sysname = "linux";
+# ifdef HAVE_UNAME
+ {
+ struct utsname uts;
+ char *s;
+ if (uname (&uts) >= 0)
+ sysname = uts.nodename;
+ s = strchr (sysname, '.');
+ if (s) *s = 0;
+ }
+# endif /* !HAVE_UNAME */
+
+
+ ts = make_scrolling_window (dpy, window, "Linux", False);
+
+ scrolling_puts (ts, "waiting for X server to shut down ", 0);
+ usleep (100000);
+ if (bsod_sleep (dpy, 0))
+ goto PANIC;
+ scrolling_puts (ts,
+ "XIO: fatal IO error 2 (broken pipe) on X server \":0.0\"\n"
+ " after 339471 requests (339471 known processed) "
+ "with 0 events remaining\n",
+ 0);
+ if (scrolling_puts (ts, ".........\n", 300000))
+ goto PANIC;
+ if (bsod_sleep (dpy, 0))
+ goto PANIC;
+ scrolling_puts (ts,
+ "xinit: X server slow to shut down, sending KILL signal.\n",
+ 0);
+ scrolling_puts (ts, "waiting for server to die ", 0);
+ if (scrolling_puts (ts, "...\n", 300000))
+ goto PANIC;
+ if (bsod_sleep (dpy, 0))
+ goto PANIC;
+ scrolling_puts (ts, "xinit: Can't kill server\n", 0);
+
+ if (bsod_sleep (dpy, 2))
+ goto PANIC;
+
+ sprintf (buf, "\n%s Login: ", sysname);
+ scrolling_puts (ts, buf, 0);
+ if (bsod_sleep (dpy, 1))
+ goto PANIC;
+ scrolling_puts (ts,
+ "\n\n"
+ "Parallelizing fsck version 1.22 (22-Jun-2001)\n"
+ "e2fsck 1.22, 22-Jun-2001 for EXT2 FS 0.5b, 95/08/09\n"
+ "Warning! /dev/hda1 is mounted.\n"
+ "/dev/hda1 contains a file system with errors, check forced.\n",
+ 0);
+ if (bsod_sleep (dpy, 1))
+ goto PANIC;
+
+ if (0 == random() % 2)
+ scrolling_puts (ts,
+ "Couldn't find ext2 superblock, trying backup blocks...\n"
+ "The filesystem size (according to the superblock) is 3644739 blocks\n"
+ "The physical size of the device is 3636706 blocks\n"
+ "Either the superblock or the partition table is likely to be corrupt!\n"
+ "Abort<y>? no\n",
+ 0);
+ if (bsod_sleep (dpy, 1))
+ goto PANIC;
+
+ AGAIN:
+
+ scrolling_puts (ts, "Pass 1: Checking inodes, blocks, and sizes\n", 0);
+ if (bsod_sleep (dpy, 2))
+ goto PANIC;
+
+ i = (random() % 60) - 20;
+ while (--i > 0)
+ {
+ int b = random() % 0xFFFF;
+ sprintf (buf, "Deleted inode %d has zero dtime. Fix<y>? yes\n\n", b);
+ scrolling_puts (ts, buf, 0);
+ }
+
+ i = (random() % 40) - 10;
+ if (i > 0)
+ {
+ int g = random() % 0xFFFF;
+ int b = random() % 0xFFFFFFF;
+
+ if (bsod_sleep (dpy, 1))
+ goto PANIC;
+
+ sprintf (buf, "Warning: Group %d's copy of the group descriptors "
+ "has a bad block (%d).\n", g, b);
+ scrolling_puts (ts, buf, 0);
+
+ b = random() % 0x3FFFFF;
+ while (--i > 0)
+ {
+ b += random() % 0xFFFF;
+ sprintf (buf,
+ "Error reading block %d (Attempt to read block "
+ "from filesystem resulted in short read) while doing "
+ "inode scan. Ignore error<y>?",
+ b);
+ scrolling_puts (ts, buf, 0);
+ usleep (10000);
+ scrolling_puts (ts, " yes\n\n", 0);
+ }
+ }
+
+ if (0 == (random() % 10))
+ {
+
+ if (bsod_sleep (dpy, 1))
+ goto PANIC;
+
+ i = 3 + (random() % 10);
+ while (--i > 0)
+ scrolling_puts (ts, "Could not allocate 256 block(s) for inode table: "
+ "No space left on device\n", 0);
+ scrolling_puts (ts, "Restarting e2fsck from the beginning...\n", 0);
+
+ if (bsod_sleep (dpy, 2))
+ goto PANIC;
+
+ goto AGAIN;
+ }
+
+ i = (random() % 20) - 5;
+
+ if (i > 0)
+ if (bsod_sleep (dpy, 1))
+ goto PANIC;
+
+ while (--i > 0)
+ {
+ int j = 5 + (random() % 10);
+ int w = random() % 4;
+
+ while (--j > 0)
+ {
+ int b = random() % 0xFFFFF;
+ int g = random() % 0xFFF;
+
+ if (0 == (random() % 10))
+ b = 0;
+ else if (0 == (random() % 10))
+ b = -1;
+
+ if (w == 0)
+ sprintf (buf,
+ "Inode table for group %d not in group. (block %d)\n"
+ "WARNING: SEVERE DATA LOSS POSSIBLE.\n"
+ "Relocate<y>?",
+ g, b);
+ else if (w == 1)
+ sprintf (buf,
+ "Block bitmap for group %d not in group. (block %d)\n"
+ "Relocate<y>?",
+ g, b);
+ else if (w == 2)
+ sprintf (buf,
+ "Inode bitmap %d for group %d not in group.\n"
+ "Continue<y>?",
+ b, g);
+ else /* if (w == 3) */
+ sprintf (buf,
+ "Bad block %d in group %d's inode table.\n"
+ "WARNING: SEVERE DATA LOSS POSSIBLE.\n"
+ "Relocate<y>?",
+ b, g);
+
+ scrolling_puts (ts, buf, 0);
+ scrolling_puts (ts, " yes\n\n", 0);
+ }
+ if (bsod_sleep (dpy, 0))
+ goto PANIC;
+ usleep (1000);
+ }
+
+
+ if (0 == random() % 10) goto PANIC;
+ scrolling_puts (ts, "Pass 2: Checking directory structure\n", 0);
+ if (bsod_sleep (dpy, 2))
+ goto PANIC;
+
+ i = (random() % 20) - 5;
+ while (--i > 0)
+ {
+ int n = random() % 0xFFFFF;
+ int o = random() % 0xFFF;
+ sprintf (buf, "Directory inode %d, block 0, offset %d: "
+ "directory corrupted\n"
+ "Salvage<y>? ",
+ n, o);
+ scrolling_puts (ts, buf, 0);
+ usleep (1000);
+ scrolling_puts (ts, " yes\n\n", 0);
+
+ if (0 == (random() % 100))
+ {
+ sprintf (buf, "Missing '.' in directory inode %d.\nFix<y>?", n);
+ scrolling_puts (ts, buf, 0);
+ usleep (1000);
+ scrolling_puts (ts, " yes\n\n", 0);
+ }
+
+ if (bsod_sleep (dpy, 0))
+ goto PANIC;
+ }
+
+ if (0 == random() % 10) goto PANIC;
+ scrolling_puts (ts,
+ "Pass 3: Checking directory connectivity\n"
+ "/lost+found not found. Create? yes\n",
+ 0);
+ if (bsod_sleep (dpy, 2))
+ goto PANIC;
+
+ /* Unconnected directory inode 4949 (/var/spool/squid/06/???)
+ Connect to /lost+found<y>? yes
+
+ '..' in /var/spool/squid/06/08 (20351) is <The NULL inode> (0), should be
+ /var/spool/squid/06 (20350).
+ Fix<y>? yes
+
+ Unconnected directory inode 128337 (/var/spool/squid/06/???)
+ Connect to /lost+found<y>? yes
+ */
+
+
+ if (0 == random() % 10) goto PANIC;
+ scrolling_puts (ts, "Pass 4: Checking reference counts\n", 0);
+ if (bsod_sleep (dpy, 2))
+ goto PANIC;
+
+ /* Inode 2 ref count is 19, should be 20. Fix<y>? yes
+
+ Inode 4949 ref count is 3, should be 2. Fix<y>? yes
+
+ ...
+
+ Inode 128336 ref count is 3, should be 2. Fix<y>? yes
+
+ Inode 128337 ref count is 3, should be 2. Fix<y>? yes
+
+ */
+
+
+ if (0 == random() % 10) goto PANIC;
+ scrolling_puts (ts, "Pass 5: Checking group summary information\n", 0);
+ if (bsod_sleep (dpy, 2))
+ goto PANIC;
+
+ i = (random() % 200) - 50;
+ if (i > 0)
+ {
+ scrolling_puts (ts, "Block bitmap differences: ", 0);
+ while (--i > 0)
+ {
+ sprintf (buf, " %d", -(random() % 0xFFF));
+ scrolling_puts (ts, buf, 0);
+ usleep (1000);
+ }
+ scrolling_puts (ts, "\nFix? yes\n\n", 0);
+ }
+
+
+ i = (random() % 100) - 50;
+ if (i > 0)
+ {
+ scrolling_puts (ts, "Inode bitmap differences: ", 0);
+ while (--i > 0)
+ {
+ sprintf (buf, " %d", -(random() % 0xFFF));
+ scrolling_puts (ts, buf, 0);
+ usleep (1000);
+ }
+ scrolling_puts (ts, "\nFix? yes\n\n", 0);
+ }
+
+ i = (random() % 20) - 5;
+ while (--i > 0)
+ {
+ int g = random() % 0xFFFF;
+ int c = random() % 0xFFFF;
+ sprintf (buf,
+ "Free blocks count wrong for group #0 (%d, counted=%d).\nFix? ",
+ g, c);
+ scrolling_puts (ts, buf, 0);
+ usleep (1000);
+ scrolling_puts (ts, " yes\n\n", 0);
+ if (bsod_sleep (dpy, 0))
+ goto PANIC;
+ }
+
+ PANIC:
+
+ i = 0;
+ scrolling_puts (ts, "\n\n", 0);
+ while (linux_panic[i])
+ {
+ time_t t = time ((time_t *) 0);
+ struct tm *tm = localtime (&t);
+ char prefix[100];
+
+ if (*linux_panic[i])
+ {
+ strftime (prefix, sizeof(prefix)-1, "%b %d %k:%M:%S ", tm);
+ scrolling_puts (ts, prefix, 0);
+ scrolling_puts (ts, sysname, 0);
+ scrolling_puts (ts, linux_panic[i], 0);
+ XSync(dpy, False);
+ usleep(1000);
+ }
+ else
+ usleep (300000);
+
+ if (bsod_sleep (dpy, 0))
+ goto DONE;
+ i++;
+ }
+
+ if (bsod_sleep (dpy, 4))
+ goto DONE;
+
+
+ XSync(dpy, False);
+ bsod_sleep(dpy, delay);
+
+ DONE:
+ free_scrolling_window (ts);
+ XClearWindow(dpy, window);
+ return True;
+}
+