+ 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;