1 /* screendump 1.2 - dump the contents of the console
13 #include <sys/ioctl.h>
15 #define BIOS_CRTBASE 0x00463L /* BIOS parameters: CRT base. */
16 #define CRTBASE_MONO 0x03B4 /* Value of CRT base for mono mode. */
18 #define MONO_BASE 0xB0000L /* Screen memory in monochrome mode. */
19 #define COLOR_BASE 0xB8000L /* ... colour mode. */
21 #define DEF_COLS 80 /* Default screen geometry. */
24 #define MAX_COLS 132 /* Maximum screen geometry. */
27 char MEMORY
[] = "/dev/mem"; /* Memory device to read screen. */
28 int mfd
; /* Open memory device. */
30 void tell(const char *message
)
32 write(2, message
, strlen(message
));
35 void fatal(const char *label
)
37 const char *err
= strerror(errno
);
48 /* Is it monochrome or colour? */
50 static unsigned short bios_crtbase
;
52 if (lseek(mfd
, (off_t
) BIOS_CRTBASE
, SEEK_SET
) == -1) fatal(MEMORY
);
53 switch (read(mfd
, &bios_crtbase
, sizeof(bios_crtbase
))) {
57 tell("screendump: can't obtain BIOS parameter: short read\n");
59 case sizeof(bios_crtbase
):
63 return bios_crtbase
== CRTBASE_MONO
? MONO_BASE
: COLOR_BASE
;
68 static unsigned char screen
[MAX_COLS
* MAX_ROWS
* 2];
74 struct winsize winsize
;
76 /* Open the memory device. */
77 if ((mfd
= open(MEMORY
, O_RDONLY
)) < 0) fatal(MEMORY
);
81 /* Read screen memory. */
82 if (lseek(mfd
, base
, SEEK_SET
) == -1) fatal(MEMORY
);
84 switch (read(mfd
, screen
, sizeof(screen
))) {
88 tell("screendump: can't obtain screen dump: short read\n");
94 /* Try to obtain the screen geometry from /dev/log. */
97 if ((lfd
= open("/dev/log", O_WRONLY
)) != -1
98 && ioctl(lfd
, TIOCGWINSZ
, &winsize
) == 0
100 if (40 <= winsize
.ws_col
&& winsize
.ws_col
<= MAX_COLS
) {
101 ncols
= winsize
.ws_col
;
103 if (25 <= winsize
.ws_row
&& winsize
.ws_row
<= MAX_COLS
) {
104 nrows
= winsize
.ws_row
;
107 if (lfd
!= -1) close(lfd
);
109 /* Print the contents of the screen line by line. Omit trailing
110 * blanks. Note that screen memory consists of pairs of characters
111 * and attribute bytes.
114 for (row
= 0; row
< nrows
; row
++) {
115 char line
[MAX_COLS
+ 1];
120 for (column
= 0; column
< ncols
; column
++) {
122 /* Skip trailing junk. */
125 /* Reinsert blanks and add a character. */
126 while (blanks
> 0) { *pl
++= ' '; blanks
--; }
129 /* Skip character and attribute byte. */
133 if (write(1, line
, pl
- line
) < 0) fatal("stdout");