Added fdkrncfg.c, the kernel configuration part of sys

git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@318 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2001-11-04 21:39:00 +00:00
parent 6b297246a3
commit e092c873fa

335
sys/fdkrncfg.c Normal file
View File

@ -0,0 +1,335 @@
/***************************************************************************
* *
* FDKRNCFG.C - FreeDOS Kernel Configuration *
* This is a simple little program that merely displays and/or changes *
* the configuration options specified within the CONFIG section of *
* the FreeDOS Kernel (if supported) *
* *
* Initially Written by Kenneth J. Davis Oct 11, 2001 (public domain) *
* Future versions may contain copyrighted portions, if so the *
* copyright holders should be listed after this line. *
* Initial release - public domain *
* *
* merged into SYS by tom ehlert *
***************************************************************************/
/* This source compiled & tested with Borland C/C++ 3.1 + TC 2.01*/
char VERSION[] = "v1.00";
char PROGRAM[] = "SYS CONFIG";
char KERNEL[] = "KERNEL.SYS";
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#define FAR far
#include "kconfig.h"
KernelConfig cfg = {0};
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long dword;
/* These structures need to be byte packed, if your compiler
does not do this by default, add the appropriate command,
such as #pragma pack(1) here, protected with #ifdefs of course.
*/
/* Displays command line syntax */
void showUsage(void)
{
printf("FreeDOS Kernel Configuration %s\n", VERSION);
printf("Usage: \n"
" %s \n"
" %s [/help | /?]\n"
" %s [ [drive:][path]%s] [option=value ...] \n",
PROGRAM, PROGRAM, PROGRAM, KERNEL);
printf("\n");
printf(" If no options are given, the current values are shown.\n");
printf(" %/help or ? displays this usage information.\n"
" [drive:][path]KERNEL.SYS specifies the kernel file to\n"
" modify, if not given defaults to \\%s\n",
KERNEL);
printf("\n");
printf(" option=value ... specifies one or more options and the values\n"
" to set each to. If an option is given multiple times,\n"
" the value set will be the rightmost one.\n");
printf(" Current Options are: DLASORT=0|1, SHOWDRIVEASSIGNMENT=0|1\n");
}
/* simply reads in current configuration values, exiting program
with an error message and error code unable to, otherwise
cfg & kfile are valid on return.
*/
/* Reads in the current kernel configuration settings,
return 0 on success, nonzero on error. If there was
an actual error the return value is positive, if there
were no errors, but the CONFIG section was not found
then a negative value is returned. cfg is only altered
if the return value is 0 (ie successfully found and
read in the config section). The position of the file
pointer on input does not matter, the file position
upon return may be anywhere. The memory allocated for
cfg should be freed to prevent memory leakage (it should
not point to allocated memory on entry, as that memory
will not be used, and will likely not be freed as a result).
*/
int readConfigSettings(int kfile, char *kfilename, KernelConfig *cfg)
{
int ch;
int configBlkFound;
word cfgSize;
/* Seek to start of kernel file */
if (lseek(kfile, 2, SEEK_SET) != 2)
printf("can't seek to offset 2\n"),exit(1);
if (read(kfile,cfg,sizeof(KernelConfig)) != sizeof(KernelConfig))
printf("can't read %u bytes\n",sizeof(KernelConfig)),exit(1);
if (memcmp(cfg->CONFIG, "CONFIG", 6) != 0)
{
printf("Error: no CONFIG section found in kernel file <%s>\n", kfilename);
printf("Only FreeDOS kernels after 2025 contain a CONFIG section!\n");
exit(1);
}
return 1;
}
/* Writes config values out to file.
Returns 0 on success, nonzero on error.
*/
int writeConfigSettings(int kfile, KernelConfig *cfg)
{
/* Seek to CONFIG section at start of options of kernel file */
if (lseek(kfile, 2, SEEK_SET) != 2)
return 1;
/* Write just the config option information out */
if (write(kfile, cfg, sizeof(KernelConfig)) != sizeof(KernelConfig))
return 1;
/* successfully wrote out kernel config data */
return 0;
}
/* Displays kernel configuration information */
void displayConfigSettings(KernelConfig *cfg)
{
/* print known options and current value - only if available */
if (cfg->ConfigSize >= 1)
{
printf("DLASORT=0x%02X Sort disks by drive order: *0=no, 1=yes\n",
cfg->DLASortByDriveNo);
}
if (cfg->ConfigSize >= 2)
{
printf("SHOWDRIVEASSIGNMENT=0x%02X Show how drives assigned: *1=yes 0=no\n",
cfg->InitDiskShowDriveAssignment);
}
if (cfg->ConfigSize >= 3)
{
printf("SKIPCONFIGSECONDS=%-2d time to wait for F5/F8 : *2 sec\n",
cfg->SkipConfigSeconds);
}
#if 0 /* we assume that SYS is as current as the kernel */
/* Print value any options added that are unknown as hex dump */
if (cfg->configHdr.configSize > sizeof(ConfigData))
{
printf("Additional options are available, they are not currently\n"
"supported by this tool. The current extra values are (in Hex):\n");
for (i = 0; i < (cfg->configSize-sizeof(ConfigData)); i++)
{
if ((i%32) == 0) printf("\n");
else if ((i%4) == 0) printf(" ");
printf("%02X", (unsigned int)cfg->extra[i]);
}
printf("\n");
}
#endif
printf("\n");
}
/* Sets the given location to a byte value if different,
displays warning if values exceeds max
*/
void setByteOption(byte *option, char *value, word max, int *updated, char *name)
{
int optionValue;
optionValue = atoi(value);
if (optionValue > max)
{
printf("Warning: Option %s: Value <0x%02X> may be invalid!\n",
name, (unsigned int)((byte)optionValue));
}
/* Don't bother updating if same value */
if ((byte)optionValue != *option)
{
*option = (byte)optionValue;
*updated = 1;
}
}
/* Main, processes command line options and calls above
functions as required.
*/
int FDKrnConfigMain(int argc,char **argv)
{
char *kfilename = KERNEL;
int kfile;
int updates = 0; /* flag used to indicate if we need to update kernel */
int argstart,i;
char *cptr;
char *argptr;
printf("FreeDOS System configurator %s \n", VERSION);
/* 1st go through and just process arguments (help/filename/etc) */
for (i = 2; i < argc; i++)
{
argptr = argv[i];
/* is it an argument or an option specifier */
if (argptr[0] == '-' || argptr[0] == '/')
{
switch(argptr[1])
{
case 'H':
case 'h':
case '?':
showUsage();
exit(0);
default:
printf("Invalid argument found <%s>.\nUse %s /help for usage.\n",
argptr, PROGRAM);
exit(1);
}
}
}
argstart = 2;
argptr = argv[argstart];
cptr = strchr(argptr, '=');
if (argptr == 0)
{
showUsage();
exit(1);
}
/* the first argument may be the kernel name */
if (strchr(argptr, '=') == NULL)
{
kfilename = argptr;
argstart++;
}
kfile = open(kfilename, O_RDWR | O_BINARY);
if (kfile < 0)
printf("Error: unable to open kernel file <%s>\n", kfilename),exit(1);
/* now that we know the filename (default or given) get config info */
readConfigSettings(kfile, kfilename, &cfg);
for (i = argstart; i < argc; i++)
{
argptr = argv[i];
if ((cptr = strchr(argptr,'=')) == NULL)
goto illegal_arg;
/* split argptr into 2 pieces and make cptr point to 2nd one */
*cptr = '\0';
cptr++;
/* allow 3 valid characters */
if (memicmp(argptr, "DLASORT",3) == 0)
{
setByteOption(&(cfg.DLASortByDriveNo),
cptr, 1, &updates, "DLASORT");
}
else if (memicmp(argptr, "SHOWDRIVEASSIGNMENT",3) == 0)
{
setByteOption(&(cfg.InitDiskShowDriveAssignment),
cptr, 1, &updates, "SHOWDRIVEASSIGNMENT");
}
else if (memicmp(argptr, "SKIPCONFIGSECONDS",3) == 0)
{
setByteOption(&(cfg.SkipConfigSeconds),
cptr, 1, &updates, "SKIPCONFIGSECONDS");
updates++;
}
else
{
illegal_arg:
printf("Unknown option found <%s>.\nUse %s /help for usage.\n",
argptr, PROGRAM);
exit(1);
}
}
/* write out new config values if modified */
if (updates)
{
/* update it */
if (writeConfigSettings(kfile, &cfg))
{
printf("Error: Unable to write configuration changes to kernel!\n");
printf(" <%s>\n", kfilename);
close(kfile);
exit(1);
}
/* display new settings */
printf("\nUpdated Kernel settings.\n");
}
else
printf("Current Kernel settings.\n");
/* display current settings */
displayConfigSettings(&cfg);
/* and done */
close(kfile);
return 0;
}