SvgaLib/utils/restorefont.c

121 lines
2.8 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <vga.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include "../src/libvga.h"
/*
* Note: Observe that when writing the font to a file, the file to write is
* opened after vga_init has been called (so that root permissions have been
* given up). This means that there is no major security hole lurking here.
*/
int main(int argc, char *argv[])
{
FILE *f;
unsigned char *font;
size_t font_size = FONT_SIZE; /* buffer size in 1.2.11 and before */
int can_set = 0;
struct stat statbuf;
if (argc == 1) {
printf("Restore corrupted textmode font.\n");
printf("Syntax: restorefont option filename\n");
printf(" -r filename Restore VGA font from file.\n");
printf(" -w filename Write current VGA font to file.\n");
return 0;
}
if (argv[1][0] != '-') {
printf("Must specify -r or -w.\n");
return 1;
}
switch (argv[1][1]) {
case 'r':
case 'w':
if (argc != 3) {
printf("Must specify filename.\n");
return 1;
}
break;
default:
printf("Invalid option. Must specify -r or -w.\n");
return 1;
}
vga_disabledriverreport();
vga_setchipset(VGA); /* avoid SVGA detection */
vga_init();
/* we are in TEXT mode. Check for availability of vga_ext_set: */
if (vga_getmodeinfo(TEXT)->flags & HAVE_EXT_SET) {
if (vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_SET) &
(1 << VGA_EXT_FONT_SIZE)) {
can_set = 1;
/* Query the preferred data size: */
font_size = vga_ext_set(VGA_EXT_FONT_SIZE, 0);
if (font_size < FONT_SIZE) {
font_size = FONT_SIZE;
}
}
}
/* We never need more than that memory: */
font = malloc((size_t)font_size);
if (!font) {
puts("restorefont: out of memory.");
goto ex_no_errno;
}
vga_setmode(G640x350x16);
switch (argv[1][1]) {
case 'r':
f = fopen(argv[2], "rb");
if (f == NULL) {
error:
perror("restorefont");
ex_no_errno:
vga_setmode(TEXT);
return 1;
}
if (fstat(fileno(f), &statbuf))
goto error;
font_size = statbuf.st_size;
/* Check for sensible sizes: */
switch (font_size) {
case 0x2000:
case 0x2000 * 4:
case 0x2000 * 8:
if (can_set)
vga_ext_set(VGA_EXT_FONT_SIZE, font_size);
break;
default:
corrupt:
puts("restorefont: input file corrupted.");
goto ex_no_errno;
}
if (1 != fread(font, font_size, 1, f)) {
if (errno)
goto error;
goto corrupt;
}
fclose(f);
vga_puttextfont(font);
break;
case 'w':
/* save as much as we have.. */
if (can_set)
vga_ext_set(VGA_EXT_FONT_SIZE, font_size);
vga_gettextfont(font);
f = fopen(argv[2], "wb");
if (f == NULL)
goto error;
if (1 != fwrite(font, font_size, 1, f))
goto error;
if (fclose(f))
goto error;
break;
}
vga_setmode(TEXT);
return 0;
}